c++-annotations-12.5.0/build0000755000175000017500000001001514466730207014521 0ustar frankfrank#!/usr/bin/icmake -t/tmp/cppannotations #define LOGENV "CPPANNOT" #include "VERSION" #include "INSTALL.im" #include "compilers.im" list g_log; string g_logPath = getenv(LOGENV)[1], g_logMark, // unique-marker for g_log entries g_cwd = chdir("."); // current WD, including trailing / int g_echo = ON; int g_installing; // set to 1 by install. int g_lognr; // unique-marker number counter for g_log entries #include "icmake/cuteoln" #include "icmake/backtick" #include "icmake/run" #include "icmake/mark" #include "icmake/md" #include "icmake/md5sum" #include "icmake/log" #include "icmake/logzipr" #include "icmake/logzip" #include "icmake/writelog" #include "icmake/findall" #include "icmake/loglink" #include "icmake/loginstall" #include "icmake/clean" #include "icmake/programs" #include "icmake/man" #include "icmake/docs" #include "icmake/latex" #include "icmake/pre" #include "icmake/install" #include "icmake/distclean" #include "icmake/zips" #include "icmake/examples" #include "icmake/verify" #include "icmake/gitlab" #include "icmake/readlog" #include "icmake/remove" #include "icmake/removedir" #include "icmake/uninstall" void main(int argc, list argv, list envp) { string option; if (argv[1] == "-q") { g_echo = OFF; argv -= (list)"-q"; } echo(g_echo); option = argv[1]; if (option == "clean") clean(1); if (option == "examples") examples(); if (option == "programs") { programs(0); programs(1); exit(0); } if (option == "distclean") distclean(); if (option == "pre") pre(); putenv("FORCE_SOURCE_DATE=1"); // to ensure reproducible builds putenv("SOURCE_DATE_EPOCH=0"); // for LaTeX documents if (option == "docs") docs(); if (option == "html") runhtml(); if (option == "latex") latex(); if (option == "ps") runps(); if (option == "txt") runtxt(); if (option == "verify") verify(); if (option == "zips") zips(); if (option == "man") { man(); exit(0); } if (option == "gitlab") gitlab(); if (option == "uninstall") uninstall(); if (option == "install") install(argv[2]); printf("Usage: build [-q] what\n" "Where\n" " [-q]: run quietly, do not show executed commands\n" "`what' is one of:\n" " clean - clean up remnants of previous compilations\n" " distclean - clean remnants of locally run ./bin/ scripts\n" "\n" " docs - construct the C++ Annotations\n" " Run 'build programs' and 'build pre' at least\n" " once before 'build docs'\n" "\n" " examples - compile all examples\n" " install [base] - install the C++ Annotations in the locations\n" " defined in the INSTALL.im file, optionally\n" " below 'base'\n" " html - force the html construction\n" " latex - force the latex construction, (cf 'verify')\n" " man - build the manual page (requires Yodl)\n" " pre - prepare files for independent `docs' call\n" " ps - create .ps/.pdf files afer 'build latex'\n" " programs - build support programs\n" " txt - force the txt construction\n" " verify - run after `build docs' to find overfull boxes\n" " or undefined references in\n" " tmp/docs/latex/cplusplus.log\n" " zips - zip archives (after doc)\n" " uninstall - remove installed files and empty directories\n" " gitlab - prepare gitlab's gh-pages update\n" " (internal use only)\n" "\n" ); exit(1); } c++-annotations-12.5.0/celeb/0000775000175000017500000000000014624637165014560 5ustar frankfrankc++-annotations-12.5.0/celeb/README0000664000175000017500000000014414624637165015437 0ustar frankfrankyo/preamble.yo: line 125: COMMENT(Only for the 2024 celebration) latexpackage()(graphicx)\ c++-annotations-12.5.0/celeb/celeb30.pdf0000664000175000017500000004570014624365651016474 0ustar frankfrank%PDF-1.3 1 0 obj << /Pages 2 0 R /Type /Catalog >> endobj 2 0 obj << /Type /Pages /Kids [ 3 0 R ] /Count 1 >> endobj 3 0 obj << /Type /Page /Parent 2 0 R /Resources << /XObject << /Im0 8 0 R >> /ProcSet 6 0 R >> /MediaBox [0 0 319 174] /CropBox [0 0 319 174] /Contents 4 0 R /Thumb 11 0 R >> endobj 4 0 obj << /Length 5 0 R >> stream q 319 0 0 174 0 0 cm /Im0 Do Q endstream endobj 5 0 obj 31 endobj 6 0 obj [ /PDF /Text /ImageC ] endobj 7 0 obj << >> endobj 8 0 obj << /Type /XObject /Subtype /Image /Name /Im0 /Filter [ /DCTDecode ] /Width 319 /Height 174 /ColorSpace 10 0 R /BitsPerComponent 8 /Length 9 0 R >> stream JFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222?"C!1AQ"aq2#BRb$r%3S4D+!1A"Qq2a ? 0` 0` 0` 0`q2(ܨ0UObD{ie H]C}?F@6lx|>4\u?q6S l%{JV_ (Q$/*(')ƌNh"28KKMs2N{ sr2kyIB,d,n.0`-||y0[f=l[QM'XAȽY'Nh5TUKMQG<.RDnj،Gq#RTWgDFEQdc1Mȏ\s˒¦CRPLebS!:-܀1hdR1,uPU3eT*йG a\m'Ty  0` 0` 0` 0`@'0 akB(# m’}- ^lqiц7Su,DٙEʎlN,ZLJ r5B6>WYfj#P6=`yA pi^KiMlof5,}( 6$P=jDˣ*GnXdzUȦHyml1]Z7 (p}`ʤJ aP?,R+ bO5Ԙ5yMA ޑ")(KYEyabeZT!Xى>1u$%<nG1˩]Ymkk儚{FA񖙔OY% 21n#úl /5C /~~hJr %cE]ZTy3fQβFRG ķJn\ 3RZJE:uvtI:*<֧2ʢh"HrE\PsU^$ِ^ܟő)sة>&[YLzEP;JSFhUy*[M=v\mTtV"ދBZJy(?V7.N/Dy2C\ԵL2L}ZDuanixR[e ehX$ߗbj+ٶ4#h3hs(,zhṵ;c'Pno2Ywty]m+d*ref1#븳 ՕU5 &C/KEI,1Wy D peb %:j ˌ&2*E֍ L3&uf>J9-(\YI3+4 9> M6e^S(wl(J:i~A 5BY.}"TVF<3Sd`4Xb;͹#jv:a)(䧦z*$p(-)~g@SWCTNE,)c8p+zu1/BL0b 0` 0` 0`]\4g.tws裩zԡ: Y(,IaAb66zuO3)([)duYDpH0U O"vVEo6=/Ue&4pquaOj C~Ob29mǨ-5TqW*,4U:R~דJ WBSlΎߕn,>y=PEoZkXQ=$xBZYgz G H$X%20HF'k>tMvcE$%ZYKC(;jFnL6ƈa\(?kr챍V1zfei_Ji dZkulqX$dkbC0DA[*ԡ1E9 |Fַ~X\l PMylXQ)q%lmaq̃[qqqE5Eݷ NoxzzvNJ03\.鍱R$M`k 4 M$C7" <ضq!4IbMFFh_ s5 X)p/H4?$&mBE9bMUW $C[,boM?yO@1i#-|f`n.ތ0ih_)t-42 吶66oўTIx뭈$a8tԕU Kk-U̼%ߘϱ͙4:0LsF7 r 3ȟ9u]_ѱibybf[PI|KY,Pgk\Һa0j#ZxojYd3Fi֏0Ck,t⫧B ")5Z#{S# G/;ks'me9{eI5EXɤSX'rAbuMm;WqVCf`Bskw$|%ޅcz*O [Sx+u4!"^ß|iJe9R5쬤`=YM0*$ )(-L[ 6b|/=Wx+ޢથϩ8L7`a]' T` 0` 0`U$nL+2q^4*p=ͿS)QĊ BCI5]SQⓐF?ƿf8 KS HG#3jw@ǕտC(i vVFYvєX򜧇Vqgu,;~ʽx.?=$uK9W8GK=<ĉVV<7DK2 ǣ(} J-$rQN520-;a67kO'jY)X0vSH|ޠ7p-х^S,pІ:@WGH JcN9F꽬9{m3.& 5NFwR.. er S,"p]8(?|hX"cTƆċjߘi&DjEnyN޼1m7R z,BT PЗP{f=FY3jB /qkv<tc 9=1J~.RD!+s#pnGXu'5*)cASEQ$o+3TjJ 47 Q~aQF$SA%T9Z㩱ߎ *ih,Y%p e+rY&Fǝ[M[R'_$IJLB$xt']1abBiP77-$ %ː HU ~ _G$b?3>kbXnu55AZ0*Rv[eH:w<7 sW -HS3*D;}s7 `4J,4-9 )*`= +RӑZovfko<9fI0zʀ`[bV[ n̫=.ZG,]3=n> JH%&hMPŪ-5?[yjVJiehWJM#=V75eR~Ы@GT[V;H48"t0U7;3|󺇊SPa+As{N-TQh1@$ 5UZmcY{þ(MrAKl &1II}(_=Uzt6OT1YM{nչsR5]<+ uE88Aq})]Nv7x1IK <},X*E}6ق`Hm,->u5ngC\]$k;Gai7`-pytbW#L)$T# ZHϾ[М*|(s:pW_D4o|o†Eye5cr.llf0` {l0`` 05԰N ij`d+yIH? Ӵ)&y<#vdM'QS\>[}eq?tLcM)JK?[ciZ.ZoB*+Sn|AS"17I}:u\lX؍UtUS0\1ko{vEI y!YYdo0MNt<H;PǷ:` @[[ $U5Nn+^Vnq_̢J6 du,cI>PA|&l,mdeZ) &ަؑc"K/ <:/Gr$0hiDTc]1͵釋V8mONѹdNCM&NQVM"F`r텔OY;Nvi&+z~省a s*hV;TI$$l'`-zuӊ.U5MybQvD*G0.z07)' 5KWq61L 7=F$׹mn*Y-P]y 3,ҁYݸub%^|kuIe9GK]׌-y3zgAU^7Ԁ*Xs 9OL[IP-6!Ҥrå++cP*13ka`zl, ]7ʪJȤq7c _\bϛ//)]nà6&8bgOlm@lc/LE$9W>#*CYG4Rʒ#,he6]7*9qQUMg{I\ QmX6aG4ί O {FgAmh-u pt،&cG,\:IUI&Br!yl3tPS)J98t̤4fTWSǶ$Ȑ$Ea 4A:\zH>PC4/E`QopA]@ $ogV4Zs -/NKO `$Э1dz0ҳ!Bwc}CQ1K3qN:Wg/d1|!3q&J1t7k-}-#fY|*\H}o!j^9DӚiM(,Tc{}.8ϼٝ49x$ۉ$uGsdKz{cq9M˒+~h3BQ"#}HMQTS;(a%eSJBTl*O*i#PV2`v}F4Kk涥JF!`/$=F%T;<ߊ(IC~eۯ}qf6Tcl<`$3աn9|T=FeQMK&:oar{b4cbUhеY^I++u5w4"7E;PAoGeVJΉ,&Tr!M6 ~!E0e5W0c smôB6/y]Qnp|{78hh`̨(y/ G*$LzlTXr>~xQ dBzJUA2Xy^^G5XWjuTSuܛЂ-oș75k>UܲBYF.wR*OOGQML rLTqcq;_vcMMQNiQ֓6-K4SՒK6ن·߾-NJ՟jJo[KktWsYiꍝj %5Md:>:H)˿+A@"}qe$ݛ 6Қ"ˤP@e'گ2xz9c𕀘Ǟ#؏f< Y+oԩP~ws旯$SNUyjcP"rZXc(u[{m[ $c-Tylylelcl{l{P.|All_[[ QMJLci@#m#7/dgggJ䭌@ 6܎F}!6Y&ݔ7*-^I1dtȅlqɅwt<4P.);cniZ8v=%e-=E=HR I-,Y,,4" !ߣ6jV(eI k9XwDT 0rڳ'ĺʡ-QHUzK,I~XЌ8rF@hη0<DždXu6+3)ۘo$:40{{p~)ȗ6WAHf&ۢ-s|OJR!^ݿ>vEFhM2A0,+/6 nߣy T@% p 3!{@ SEMW"vF>kLOHi*(*,Ǫ0#P&c\|H]' BBk 㒪X !`ۦ@0MC.cIiYUS*`>ݜU΂DePĉssWn[b gC|)%QlK هΡ@;'QK;qj!)3 $[Ӗ gAx^x.lX簹ţz+:h4ZA6{Oɟ=x⩞WXZ!xBusa} vS3)JZEvJ$#fW N+h˰ _'v8OCF-eM);+O{fMd/Fq%%)GWX`4ը|Ǘk\sVUMRРMf-ֶ,Ym4K7RI!Fֹb%lqTV4ZXU'rlv|QERi_ka (=KF؂'v .kN?LB#jVywgcr왮lyl; |7RiGZH夨_&:Wf|4[,\l60f\SCِR#N:&RT8i2ҺNby n7>L,tg[3f15DԔ #Jn#:FK_/ŕ3*U,{K=00YM! |Ơ{0&**VlgfFlglyl*䲏-X+&c9Xi#JBP{I;3fwK1s\6, e!WoOkSV VV 0 ,|[z#OP* |G0ōrtH7q},9nxuڻ-rd@Wn,I}%,gD|Ybi$ WqFT6jYJsbÒd|ul  rׁ@<}Α[¾XnCmō7=˩᎒9RDEpЋ^|^hU0aV} /LM"ƪ{v؛nG&9D$zHtV+Qb-me~fU5&jVHä=:i%,RFȲ ::z])AnlG._Xvђ(fUhj)sb;yC[BjU}bJ pIƿC *b*g~>"T4r2O2 h7 [[=TszSͩ@Vwz\ W>(TDAEF(4ܛ w68:iRJr/ ,QVGVرv jwE9Qʨ@:  9r=)wDZiJ (o"N˙,DZ y%oiaġ/8HU[0Qu=m#(Heآi |Ӷ6l;1F8N7:p(/~aO'84ϗsኂ]gem db.厛 "> KdAdviu6hKVay ; V&th1C4U_FGKm :*R58v"0ݎzaE_N<Ӊ)HQK11Dі=1CBӏ4~9oqt:VlvQ"!=.Iyq܍uBd]qܕ'x^772$5;orO`,khLJ}dȹ@G3ZFC[Ez'^,6Y] ~}s/RőRײX]">A}gG8WUr #+VK' EnHlk7:q:hէN 8,(E/piaFĊUgup$Zq]07ci,\24O$mIJaǞۂ=Cezz$40\!{w9%mR",d3(3bvl0,[RYuZ2EaR6Sk^d!PwPv׎ Zʉ՚@inƩʧ:7hpXu)%>eMpukӷPP$PYPñ6t9DIUa[lɘ$`$ mAqƔ%hxeGu\1ruj~NJV@Jg%3y8d&qRTM+4 }p15JvfDkpHtF-<9v^R%hjcX8^J8kbTZqݕXg|?WK}2y~Nx .Lt\,I'JYDKm)pGn{ Lꧪ(X_7tC^Gñc|zB{ؑVDR(v,kG+~xTY@lUOk撲*(*dkA~PX ehȬB4G'J j3%ʭ4_,Y= v:xe' ƬM 4H&2D[jnU@hʛbl2rWnq%QeE4Uy&UȺphAFJM4w$`0lOEQdg$#dTXXj/uD.ȗcPen.jFR$h_x['L*|-;Z*`D?G S-|j99c t #{m ̴Kd!ƊZہR /.|mMڶVAI>f"{u@a seӈUHݿR:a|tg !LɢGHɰ$njfyHPKl mSD endstream endobj 9 0 obj 15483 endobj 10 0 obj /DeviceRGB endobj 11 0 obj << /Filter [ /DCTDecode ] /Width 106 /Height 58 /ColorSpace 10 0 R /BitsPerComponent 8 /Length 12 0 R >> stream JFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222:j"6!1Q"Aaq#2BRb5"!1"A2Q ?BbcB qd3O-ŧ<`_lSiz_@l{8u#JjR-Hv*-<2Zl&q*pQfp׌r Q&bm}1peDk!/ es-ZD%$G  6zhL3I_)b0[MSHqSJD=) l-}kPs+!*LJT= S…qoJdHBHoUt3Zm{zH;jzyj_*JbRضژX+|*a+,Q8IZ=O o耝Psa|%3SWOzo%)bbb`%1["R闲Cq*%Ki6- (Jtw'RnR[!X)LTHV6vY;C6ju-`݅Ou /BNa:j(Y0z4OS,ýlPC[IYd5a%,yZ(%juZ5O a.Jȝ#;,!˵ enA{X= ʀ)̿-/X*ON8S,+IH%f/HH<[vjզiľ_On-4̥E1)#svzfu6.!BŇ du8oI;k?Zfs4BEv_[p>.G*Ng4S)mžpSUQ imo,I|j$[4 ʺ3xbo/` Z]jdi! n G[Ù`}٪]"aϛHDK ͷ)sp-~G9[qe,Tex.5 4}5 C%;Ű:ZM( `yC5>Če:N.A4Be_?rOzn| M-MD z;a|\ڥǰb1 3T0/P/$TNϳ?ZY#M4}V&z ,{aU Հ J ouFFI$rJXl n6\xVWԠ  {:=A.RV`ƁSA^SbH*du OTKѥFf4›s>;pMxr4r2ف)"غI$Il QG+ȲF.6eͤƓ7*ț ג+N cl[ʑV* Hu)Xpl)5y`cz endstream endobj 12 0 obj 2222 endobj 13 0 obj << >> endobj 14 0 obj 2222 endobj 15 0 obj << >> endobj 16 0 obj 2222 endobj 17 0 obj << /Title /CreationDate (D:20240525134617) /ModDate (D:20240525134617) /Producer (https://legacy.imagemagick.org) >> endobj xref 0 18 0000000000 65535 f 0000000010 00000 n 0000000059 00000 n 0000000118 00000 n 0000000300 00000 n 0000000384 00000 n 0000000402 00000 n 0000000440 00000 n 0000000461 00000 n 0000016124 00000 n 0000016145 00000 n 0000016172 00000 n 0000018533 00000 n 0000018554 00000 n 0000018576 00000 n 0000018597 00000 n 0000018619 00000 n 0000018640 00000 n trailer << /Size 18 /Info 17 0 R /Root 1 0 R /ID [<5f4054ab5abef4060f0bcbcd4364e13dbea61c8c4fa7372c08e1178853e80b54> <5f4054ab5abef4060f0bcbcd4364e13dbea61c8c4fa7372c08e1178853e80b54>] >> startxref 18812 %%EOF c++-annotations-12.5.0/celeb/linux-161107_640.png0000664000175000017500000027262614624437014017561 0ustar frankfrankPNG  IHDRVn>u]IDATx1Agn@ A4H.v IH1E@<BJ!Z*V*,KT)D9RD,’, ;?3vR,#&q!L)BX,{UTlJJ*Hg}9Ͽt:| q]w0l>{H\~>8>C:M|eY!0 Bpqb,`WV縜~:Wtp?XVu; pe? R h(d N۶W:hE~<KV Ðiz(s-=P{vY 0M.R>J ZٗL&- ] 8 \xӯ˅:)Xmι"k wnY0xsV>u| n $v ,PM CjھT׶<}!2Alu!LRo^E՝p%bL>=O/%CjAc@!CŠw*DtA[t}/u>y >3m| ! D⮋aDL^O3y0} m"X4Tr rTAAP)zEhA!kP/*@/%FHSQ*jR5fw|L̰캵׾~۰d}3N^8x(ޝ={#ױ8paUڂx<>1,D (4}@JRzubl |L<%_Z6qLH$bXٍ%L m,lvK꺰SRȼLFUAXjC@k4YONi(?ܪ9Uɹ5[Q^4^?.J븊aX,jW$ m{j,bA^ebQV FLDBLؔ;&q^Ŗ@ǜ09rs6FX2a`X,K;Nᣖ4-o#~[bޞl~@ hV*]` 1FL&[ߺoa;KcwQW?kiJR08;Pp)%Z*ЊB"oZ0u< $@x$ /v޻soeL|f~saܽ{ÿQw}%#B£233ƽ6C37-b~eQ$1V0|]bE͛I`.~i2'Naí%6_xK_ *-,,L}.M|G#7J]`ƫpԳLT (>},0)xHJF&;p@ aAHHT䒟fqSO" S[2XrYHj޽{eeeYx#*1 ^ݔӄ  ((q={v;M\< #ϣ2ս/Tu!ĥKr09"¯)*9N~0_srr~&#BBN<,0AKA`2@<=+O}b / />'UM&g7)\^Y`rssY`LOx %Zyd=E^V!_Fʔ ^|NQyr{IkLKK[ LoiḏRdv \j|^7D0 $F5Y'q1b@r"|Ht/O˰a~ ̔)S77R@=ѣGw!!,+ Bteڔ#E./ >D]>]}|OɵMΘ1;0sLX8m?=KNp8M6]#d 4lgPސuTWnvp{b^DgVq S[nmʛczSX^ޣ9ز<A%0K.m LЬ*^ȩ#S-6\4J\;NjA,NG7'{, 'I4"J֭"xwnc$hK{r&M B"aYV#ѣGΪ^RHi.橚h)+kե2PDbӞ~(^ {"~ {wT PsIBOӧ(}ވe9_8-g9E^RK%dޣ25f];R*AH(B[liĝFn>esUzz*яL>24]ܵ$`vRA&B>^v5"ՄR[df$s+Uѥnԛ,AwD?L;y|W-q1AHH7̤x G2k$_{x"ra?vOؚ,Qd:h{ф:55u!!Q}sii)@{qˡkk EX 8rr"HdAtv@<|Uqv U]XkVV_AUĀ8G24&׵9w 6ihb|;`T`wqx& )RE}4hLOtlC)!'q1 rڴߟx|Sg8 8-ME.wRCӪD szLA|՛M[yEqDHdj66'qFN}.>w 2~S$r#3c~}.I ض!B=qz>BJiQ$de8yX%.´Rly9{}*(*b0 ubգ̷1Pw=L E 5ʢĜ\K8~":ֈ\Ν;sz, Ap^L_nt\UDQt:>U\}#SA'87WΞ= ~˹'S?adZンyaPR}A 6Q2xɏ2j+r:'ɥ-E8p`*s[f![S nlq93c5Q |С|ApA [si@Ά2rpͻ)B=y#@AAdTbZyhR2C%xDk RZl,wqQEiiiAQD+`ffR)xcK,5Sq1AD&Inz>{SNӦŅ*.}C\e׭[LAanj'`ڑSfTֻm@̂zC9Y?8>Narh쒛3.8HeM2wZMG)8o6)((x@Ec2C 6G3tVq2>5JK|h5NX/!Ei̦M|O6GoXU+*]J R)"Ă AuqVQYŎ**(Hdf2sܙtZ $@}=>70={h͑B~6NֈSKpCs&y\05GMxgwq?Kg.\viP*V&zgN,?%Ȉcn}7Y!sP-zڈ;_f}VPSܗꕂlvs5qPŠ8r)}6ػ%xjO%J@8T![ ̆X6=0lD+;ŭm+ -r {?1`~'[fL+kz-Q<}^5;XgWU"ʠ 2ަKby0f\.WSB[Hm2@h7f+-ٳ[jjZm2̸?M MSec(+~0 G#Zi4^zQIJǼ3| fو(tvE2/L ufݨf֭[?!O g;(m'K $UFX b|YY le`ˬ=;v`0c7f,z9G1^9y34IG.Qt@V1chkO堀y2ֲu(M( ӅA2c^J0p2l޼…{9![^C4iM&qj7 @ 4Xˊ-[馿4(L.{^$(ޞ><扦ktCjgtF1 8$S̷$¡\b';cX;rd3#,D#5Oqע0wE鰞 dhJ7`HV/r7N梋.z _y睿Ǔ${6c٭k4k.O.)dNA]Q.6)aWY> 1ɲj!{M%L@hxX:Sx| ƽ$0X0yƽCA"k6s" =Rdk7 ao!zꩋƓOg!<9UUa ݦ='Xu"e^R 1 =K2kZJ?@ 4 ,{{biV <F0ZFH_s_3w0 casc)Hޙ vjcq)C@ ,4=̍7^ɖfx (aAoz.h Sc bUb#̐Y܏/Wb0no=$BC/X=oAOo >;NpB I:TxqO P4scMAjАr7^ACG^Zx ᮿ/d!3]5 Q9,$bs#џ@ 2Mip,PcfExqtLIc=_8hce*yWHN(6HA9$Ʋ'xj a?s*'NiaKƊоV@f;tTSX\dhb3͖[iy]D@e7EʗɏylS 5Nا҅0p6IK/} e5[-6"Si}Hᚆ9Gm$RWi:27c2rRq$^L /7tS1ʹZ9M|dVTtA(2\hDRK*W#szxl@nӧO?0 ]٩X]X+nuo#G-{ 3Z::@MzTβ#&UU0@W'j[.&SL@q3m46;[{̝dkĴyx#]#dύuG9<&M~HBqcD &AKGLٳg_`_'l6Mvh5On~`Ơ&U܊3>Ƈ͝9tgFI캓mE[f9/ǻ]v٫I JX SL ~qzq/CBe፷꿼y)GSi|lDJUV1"L;, 2_Kn6ߺ/:ќ5D%̬,Z$Gl 5{";˶a{5;.rdhxieU㸕얐D7ہ[ou:-a \ˀK/}c!lyygIyj)V%I=ɞ!=@ 5p誝&`8Z,;օaz*=rLºX2W=sypT/rec"Y4EAVi-N4CWiby%D5GU"=$wj#ˡNZl!"o.{"5QVȥa|)[gh7qC}ʊY1z4ŔzL c ۂ\I0_9 R |MTrA4V1s`rk?HG2^R)f 1ህV\vսaT%T-}h @ς%.bUԦd)1ሄm,= wq{N8HōhSr ߵ"{0'-Gj,;k~]Alfђ$nٶmۑdUF ,;J_Z t#24m"-߰􈁮; ]y5n " 3c bh9dl<~XSO=u b# g|Ia`dD#]8N5 $d5*>N b1> G K4mt!#{-X&$+?2z[ [d CĪS9 V%fJXȈ%sJﴀ$jVZԢǴk! )#=,eΜ9,-cT@C 1XߓՒMR ne 6:{myCפeʹ2_tiL+dn /8!zMA~\f^;;7h~)C&Lp 1ᰆmrDm lXSEZsUdO`FIv‰|(:Id=6F/``b ggw̴WOJs8+*|_T~+]Fԇ9~,*18dcUBadD 3Ov =Q+{HYO!eEm qrP>qPY|uq znDS",!堀bUN+0̴2"fRFLREpχcw/bd/5ގY>̱Q2׆W閛"*"N}ה+Hbߟ|C H$ZCʖ&@8,i,gףc'\Tf}xiZ}U+ df~QȒDrj+[UI/g%d FFZԚs\ vKHD._~"=@ vLɉ˙`l nOqJd̬C扠PEzDͽT@$"g>b+'I83u4dd[m.°2tu1?M ?mڴk/";Fg$!x(>o4t5FQ3?SPJST۽/zL?p,1ᰁ%gddUtnm /gXօM]":jNQlJUEp[jl`yO$;AX婆OjGOB|I6\lQJ8_:pd*pY"Oit,|(vFneoW&e(G!p=fK GԄ?שnj;F K GmoqjVc.#NJ,")GF8YQB:*p+WSlٲcBMocg3Mlr(V|q͉>|!gU00RJ#r{_쵤J} U6:ƧQd3Ԧ,#=@ 4Z{jsY.TZ!YnpN}[Uas1:"|$$]n\ƍʔ2,dܹ &r 3nڳ;VY_ 70POhx<(ea9q7D92XiͲʀ?X$; K#F;6%%UɔbY&k EkسY%s'-9 ?҄c]?zR^M6(q"k.z̤I"=@ z 7?B9ہq.KE:$XN;tr>mKӇL?/xt?q ÖqZwYI'~2a?MaЇIP1i(1(Sa,,gs3(6N^kȗNЪ4 Mlf_K~LF~њyl t9b2Xxr6Wbl\(oXiRc|fʐaDZ\PssH>7%F@ {=b'販4klO1.boX߄.Ay8FUG.3 3\Gd&89=8n1z̍7xC~?5HD>:WE0nZMɓ;-هcfg8P@q;N=gp?v q B?: d4OSuPPhqPWleP W!fD#&F QY]sSM#.N2ظRLʈ`B)7RcI1(/Z_ʄXnyNN4RKq7vݾ1CH! EG\Ӿːh5GkJL.y:O "ϜcV N6hL'=駟>WVd '&7e 6"$^GfK3еR,.4=/n @a9f -_lr̓ i6czL11?q gH3,VĩLnA^VAN.Il|fC?$S*1s? )'Nf 2z )35aǒy)2Ї:f ʥX{75ԦT*#vۏ}w)8N6IQG"c')fF̺|pN~!1O\ f=&NF}ӉdB 3fh]E,JfJfe}K#1)4tcI:G:8j.o]j"=@ 4:MO9yST U?xy)=PLw)VݶF0`e7mXF:,2dvjmidٲse ogcu]HnUy Miݺ[{̂?3>-*&DƉ ,I8=6 a1O9 c{:^ ^7އ0ƖxRڂybSGyU?G<$C>Bi'8;ُo `ڝ!b:Fc0[\[e)u7 @8h^Zc+ܝNv`A$o$h LEN'[`Wܱ&̼i#B81%d~ o/r!]NrfJܝ g1ßoV3ALTZKxMJk~/2m5:kM(j@  2yө1N6`ck۟Ef~MDLQ2ؽf K`& e[2{ty2vAD\r<_Ocq>XDee̥ ]e.?}^3)O*xtnfܱV<,[imiQ'rə0۶(|Oz @8gIl8S,dobC&Fo9B#IEj! s94Ӣ"2eH˙DɯTA2ъA*"Oq] 5aTi_@oj>'1#y{]vFoo}.[&>{,g"JU puj%s-OV2 >$i#|[nV00/I j)]T 8FT_vv-<6=B@Nk- W+m),8Iq Ff;(v"-zHO7GX 8%I(6kd%C [/vZXӗ5Gֱun{Sx;̬er30+ 7Mn5dD8"Ǵ6I*j~ۏ2 1QիA:Ti1m1TRjpj;5db'wj#=@ ȃn? AaSd/t8ˏ{s*YSWI6IZi5 eX %T~Ѵ6OӇV*w;1tW++Y!hK/$sY'4qMj%S?Ǒ @8 2Y<&:)7xIH(F|0WSUL+1suZ1}B`o{WYeuk{N->R X'cIRLϴA|FcnALg>kpr)ceƦY*;Y/Hb'c¾Y̙3o6YxiKVJu!_"n$v[IZ<*ov6̻1O͓{Aӛ!L1`POf!5 d٭A|.Lv'\,k4ôL6s7XԪXYzmze%sYᴈq̃B_マAD͛W^i%=X+NcY mUR*tfv2;@`G +Y,0V{ ɓ[ @INSTY9y؏a|yshh5˭<\2Z꿜24=AgQ̊AJQ]&ciI 0JVr!>yK]@abH q;8]M袋2@W"#6f ho !^\0ܺ_sjζ쟂P)1dnV@"8EE8SQU Ʊ!62U k̳*V/5y#94DX,O5_~ej[omcrO][6#M\40ֻc{84[hx01L6N:i.W!{ `6"#?WչnY.}Ɨ bޭe8Y dCMc$ŲmwxRܬ6:GO>ht@8ay]s5o2&3kz>^Vĝat`YZ0)G)'J;N){y{Mǔ' ˶,?ۏ84~Sd# X4hǿca$2J iGW I4]0פ>|m 2:Gldk 2gL"`eɡ\Xd)>B8K<IGw%UIN<3^=52K bA,<#$ *,e9].e8եA%Rִ?0o QSwxM'{O=s0l'^|FQ>mi+Os=ZeQkI0w{F+֘}/o %atMW9'Y Ezd#Bla`<<#$:pQKf0xzL/Ӈ0+K}vK_#W\,"sRQ^K=@mA߿.rcx~+(xnb߃siW֤ nDZ{f(I$2 4UE2]6:e(5Adɒ?'Ȝ9o7mš8'1ܦblIu5o}B֍I>.G w8%PݑL&I3]ğupMʔQmE:ѫDGsvan`0<-O1-[DQk쥗^>A\}|o Z;(~,l: 1oލ`ꪰ$!"rٗk)u?5y QQ;m'I&޵UO^CQkn! WfҡW$Wr ~ CIQGlqc?PeL{-H+k/[cl%*#dp2bE0|lf-rÔ BCrh%o"-zENdsXn嵻<6{qim^LS6+*eYI[c}Ҭ~_*u!E#%t$RJE^ΰay_3ϩx_ȴY}d'ܔP;S1M?%'UF pRS$CY#J]ope@isd?Ǽ10V0߈M+^ņysN4-[]â.AJI\䔲@MzmU yj൙0IDz[$:-g$q$o7] xxS%i3 0#܌3V%N"J?ױ\[e2leN͈{qiZqy(F,;*5 ~S䶠iZ9yFi*c\ pB #~c0~k¯,="H S7D"_n Xgp|t$GQSR?h~g?"?J0ĺwǶit@8LaK\LOhb^[]:PLyK-#/hG͓Y \y:f,SN9e=MsdAch7tMAKgy탰v)N4TCϋkV *s7LLL ZD6Bct…:R,%ęה?UHSXKk 2#BXbN5VCUe7=E9qyf+'8 Mo} WQX+Ч|+Uλ2V*w=xS5u9Nk0ߞl"0gEОyP+8mРAT=X_I0Ui7 }c!2taebۀWV|b';/Wxv{l߻oT]vE0|y/Ser#_j69j,ro('އO:1a|C:bl{\ZTj+n{r_s'! -[9qkkj1а z.kL R5ōXO5!AJ) XvnCl閝uN,x,l9ɇ! (p0iܺ 85'N6/[&~g:_LQ? dѽ&ȚiwH <%Q'0m4N8=K"3 o a_mξ-ɡ~-JˮF1,{kH"EtBN*( y.Y.%$8[h#`D;Vn;Y=EJ`U'&U Ǯ50~xbX7mI`YEղ xg@VgJGJ˷%dgOb8; Xr.iVjzz0gjhr)=ZL.T*ʐ!$˖nλ#"G|.u/uy1 xǛrJ2)UT~*`p><[G"HLfV xu`.ϧ*;c8Vm{_E]4eg2DC  ӧw9A$VC󑾹~õa'W"kSY~߼9F@xB? Sg"[N4\!<I;E%ubqT "ƀnV6&i.U&әş^"{)5xc.4k +\0ȄB!`#u8>>&ɣ˙^~CG?&D"mMX T>rtL΃-u9%ʋ/2`[ Yd@uTPL9|LJrf Lë|?2UgcPwPˋ[c=€aAVx<}fXi[B:v F$:dzEMaϴ?<m/qfd kX6xYybγ7\lC-8Gg].<ɠ޹GUy0h-H`+Rr)J/nY0ID@Ћ ފ+TU[EkBZ@B&sO&$pscsba{93̜76 ?~9̯6I(riInkǚ {R=j `ÆVi7 J+!ϡ:g测/W^Ƙ1N[VNhvRYǰݰ9]kTPc8:ٛenk`)K 7=ǃseQVL]0(I6X Τ,s9\LO@ݻwϔk,fuR-={d'*U1fK(EKukm/g-GIuZ/"s{I(|\ @a7ycq@jzVCg1 ugRgDIs[sa?Q}V>=(4c!@.]6;l|-n!K[2&ٺp 뮺cڞۡVc@GÄNBuxM{;(1䦬%3Tt,9n\Lٟ[b4 6W2n7t _1=[޶ j,ᩩE9i͵Vo(NW 2#~^('q'$pF |YrVvf$lƿe!3[U*Uب60ޡS吚ǔ-~JpZ\yz27 -f:!\ ,hS:nkAo5Uo+ol6{a>p._۷/VkUVi'ֽDҺ^t&[qgzd>=Cp o|5Mʲ Fɰ"k7ܯȧQߋ3YDnULF*s8 /}^~^_vc˜cxŘ8DXdYhKKщml"aynZm5cڋ6+r9$ \"aur3I&>/3Zr|2,Q.!37*.g 7VTc(g3mWNCn|wab&,KWխG2Bƒxf8%.Ce|♜;2t/j~^_gIU&Ibʬ q_Əal4y,.%MFijtI`KR$&OxDlVOb֥Q!PmTAIZ Erł 0y_ۣGLzftSO=uWZRApIVvo_Jwb\,Nx6\}aΆ+qߣ122cv_oԾ=p'LlcNyJT)^F 05 H"?sH]oq\rwq z04B;&2z-2 LBb' \>B8d>#2ASqW. . 0'}06.޽StVc(=nǏ Ὦީet!Z)<4"AVY™^aJܷ /$p{LY09ɢ,=O:7p` {'^'/' W{XBcNP$v;\2hDbGF+?1&y髍{1kJsLPKc}oEsZ3 {c̊t7^ %Va /vZ a1D=ž16 kzW_ isOj?iJs(O&q#cG*Ĩ'=ߒ{Ў7\f!ß!㯼Z -nd&ߊ)Fo@'Eq!>Ƚ5(RIq8Z/#ۥ7긭 VGR 0ZĶaU.O0<#aB kokXr\3 QU2@?G $H|N [+0c/0vгy҆G/^ A!]y$cE .4xQ2̛~r05E.1 Eg^|1`FόFJha7lijLTUom\ύ;?[NQa0^*_ aUxJJk$@ijp$J>):n߻Tn^ƪCjxZnYQ=H%1?G6&1r5=(AϓY`ؚ$Gaߴ\ Þxs3Xdpj0CsPVF{PE[iyiVcjО ,B={ĜsgsYPb,djtn`01l`#.~:!!|g.`!#L¬a|Y&`MFٛHS`gj$ 8OG ;50El`skQo I|nLSG;\LxϷ.N{!\hlT2fW@<V?\毜/Ӌi9sfsm1?S4HV1oĒܾ,a%>)*'3'kJ4Ӣ;0yZ:V ,sKpX-rd0q_.\ݻwۑw5SܰOBE 6`چڈZU]o15R[.[/ wlVP͑WOGg(76,8Xx--ʷ.YK{-IvLF:,'dze2|GWΗ Mq_U^l @s m7aa̿?Na t2%w8Jpys3{X<-5>ܸX/u'4HOs!Ч> Gl6A 96{L,gΖ9 ?;h.|X 1!&Hey%`9,!2坻ƆѸc>K쏍,{AzӋW{]1 .-@C7Ϡ̱9|BK4NhE9*̄1:uihYzꜺHH.`04/ ,ᅫ‘8qօL4`CPXcPYǍ<=+aИ @bq~60 ĕ09gAwIX3WGS-(0K”9} _V?}z||.7tC26`(pBNZsKJE.r, (T`1h_OD.ID3rK;`jp `jI<GOƟJR_%% P_w+dMMzE8~k[ZÜYuQLň!  -@ TZE`ݹ-N0Z`mS?,Yvp k& 2v}E%#1)!4Y4r3 x;7\bB8Me_f¢LW`:nvXVD qxc!qlwi…`̕u-igNOex{.IL %aM"ݲ@)װ*aνh1?=֪b= IܤmѤM&>VA X^4r6"(F# x oEȫC Cy Գ~rfYkd}Yk|9\G>(O3T\ ֋ &1\I@_ҿfA k4VM(hqa \=YӨ4q~G,Z(YzuiӦdϞ=#G$K6lؐɔ)S(DH6dabZq^ 3fL`dʕɮ]Ç'28l߾=ϒw}74i J|(R۸:mpg+eN"Uo6Y0*dZ3lY6el hyulgΜ tHQIjCCX3ss2m cdDfd,[|"U,G jeVYd8^x()UAY<{Imۖ#(G&cǎ%?]IY%LS^&ӦMCAiE dH6@)5'X-| =\r$>gxi.:{?( 8ȪW@W@bݕC%@ Q?u|o)Q #֊YA)= $|{z-E|L⑼*]c&.b1c}L m, R # w;h`cZ_ĬX:d]@ձdHm!OP73~PVM ,fPXg^~ć T6zDnY1ؐTQx(;5 ך w(rIWbaEG"c'2̂i"k* :::{rL<9+Nv`}=9\ `&GWY )J,1X0 U 6R+Bt.]8"ظq#/UegLiٓ fͪ|t޽5LB 3+4C2=q磫C֒8ȘadLqL.и[5a4^EC?_!pÇդYVdu& 2.(?vǎG͝w̥ ^o\2 %u뮻1u>3l=%`0y S S,L1qU 3fdA+2d*%S>}=:T+y CFPcUspaV2˗/ݘ\!Aj,NMHFL^Ch\`c2g 8U!?0]Y Ob,Y|Ǝ[ 04Mmd?@qKpaf- 5vc&d:dZ3AæHi,,I#vJT2(hEHp&1j'޽{%q(EVKLIÅÅ:+feHX?!Yc@LQȄM($ e<_~Z*N`s۴x^2O::·AKYp|ܥ"Yx fF8kZ7δSQaQLxڸBf֭Y1#9aYe㏷|e=H[p0/pulY &2EAcjÆXTӧOM<03E<5:FY{"jw UP¬ \~bOc?~CK1`9T d@\,hpâ*QF-D҂ 0(M>1YjU VL-?%Y.Zl#`Vx2mJ \0y Si8F 5lʓU"Z}YS^U6 Νѻ0Z;5fb5&ƶ-x AId>!4aCߦdPp*@1Y4BfԩYYe\3ƪƀ?_X1PKYn1fKE-=njbڲPj2yx0*d[3n3wح"aRbe…6KFpPɊX1.Ŧ~]-eMK>`HK!)dݪa,3SO%r~FPيɲbp{!eYS- *N5F, *TȄfݪÆ]a^XdzŊ8j&\F8ia\cp;:pHOT4`؂yDb8f \p_REE&#\LnqkJW [/L5SXa{k;%*8|@*tQ\equ5\jX1zI 0&ȸX3n3'8Æ٩J`ذazG] L =V.-ъ)zOCK>x Wwh54ΰqs]~}"J"8 1UT*FbD+E)42ၓE/k4d~u/(8| >0aM"'pq^BZ1#b; Eµdܭqj6\)dQccjr\"\V̡h^hh `H#U.)Ū!ȏ܌ᅬmOiGJ2eH:r.+V̨X㯡ewrd^^Ge@mfUc Ϙߌ#2dӦM3PO>s4Z1e A jUÆQς67ٶmlX01RVGƌ2OG!_s51j=2~dÆ3uN&4fQV1*S6{UK;Z1zׄ >i2sf?lp5S ,WQ*[%X )k\:ti=߿_ô1Y2L^huɲ/X\GEo7 F3\Z&cɔIx<6P]Heߚq 'h6\_{8ELy1#qj#^CLT (E=)ae68ݓ?8 |SFc.n^od8L!G"L`d3h\`#!#pw%(MֻwoS= 2EWF?;2?mlyGy/S:dL.ڂ6zlGС'Nh qpm:rN70l$nlce!BJEZ0\fvи[52T8X0+V0.KݭrNF,&Z1 +WZ=-ȴAƧ5q& 84eދ0'O8;::L.Z>L{Qs/ceJDxZ0 !p\TȔgMAU?/-8BMAT|% ) /wɪPdV^6f[.&$%S\ݻO]=[WGb4$)ثrdlHzLu \ȄMMf yQP/|.DE"K9pĈbs7o 0?nm&7=lذ"mX22m 6sU `hQ;_+yMQyb&M$ 0\ۧB4$Hٌ3l*Җ]K8~ضn2IKrC({L# mMV`h_+ݶm[ًR B;nIw;-M6rd~۵Q}0jn@2 n͸n ~Z,EI{fJHϥȺTa4>; Loopqls׎ltKi7Ҁm?{ )ۚh6MujU!c[EA澿M6U ;wL7zh`"\JZ7um{,dBv,[7e 'W}i! %:u-,E-ڵk˴^Lny#HfP <ҟa0.aixZ߂c)Cq%B&O@L1;hܭ;l*`xO& m+U'&,Prteљg)2"#eA>o,.7sw9Lhk'h'瞌q 0X\.&&=!AĂ߿#oL13y[Ki…,Nl dBͪ0iˁ\P03W4C}P٘1c*I-^^dR pil[7#ؽzC B"356sU#) }"UYÇԙG4`A.DRޖ?RiYFrN @%@d,br޻wo-4 UsWv?k>cUeOEvYg&[Ly9ZM& Ҍ?S3:dLA&5ӕ dK+mV 1EJ~UeQWU{5DKKt.W-[/9iϾ}*R2@\&JIߗ&T.E']b]?E6)~iI5ƬLF *d\ c)b1nQ`a_RK/d]@f׮]_\HӇn ld2tPy*lqd=Lx%2qffA6ʐ dɒZ]fAA~޽O8G 2$Y|`e˖d„ Rs`I&IX9FwXuY0ZC%4d* aMTVflPlV'wRM1' a͛7'2EٜyټTUɶ8ϩ}Fm>~n?Vk&haB|p%]A! *LHukQE@~~SO=U6/U<4_2YP S@HиY5сlG.؟lPa ;AZKPRYobZ}-\/_ ,Y3!ASU#) \e?6*L +1ou]SJm.,ld]n@*Ħ#qcBBjK@iUZAQM6VTDү9ygz{7̴Λ;og{c:*b$MM:u O8F(BUU Hˡ3NJh`Kaa^4EqfeXN3fh ~ ϨYըF8 Gڵ)b.h=2-C-di}RصkR4^zzzM^(jacO%1"Qq4U:lԁC IPBLI#:^B@H%AtQ^ *bu,k&X'X d^63 4 U0d8A*fŊ),]]]8͜'Acɪ|ӦM mgg gxF?SѢd ~]fIN!xAwIJ4R.4~D2ҭAA)|G4O7KVJ ~?+>mqLEd (G1Xy1s΅#/Ni(H~Ң+ҤT.5Ixǎ\ 0Vbg%?UAJeT 'Fm6)&'|/T Jv?wD*s䚫uKA7DAj>;-Sc3}<lZr%3ٳg- L GEQɠxKhT0FNbȉ~W'åVNq2?ˁyւ@%6qڜ2-|E.cO,ysi xy1ötkQ 70-5d 2F 61N*EGNvW76zHn^+#R)E H@QL3q^){HؿvT3=ͺ.Ytz~ ?c\'(Ϟ=u]{:t82 Ke{!me˖?1p?] 8h/Kd:v+4]>~X \`yEr[[VaEm6,:d(:0 OtAjaV7ZLrpYxqd%3}^ Q h8bYh=%O If} 2 9 +F]ըÆ\*ʚ5k.N\?WL {,FR3o8Ue>ɸ .)l]Ztjhhh 3 0Q/F8N% BoLobS-zR4*Q V:\:D.)ǪLL:][3o =rי3h܆*p82| !tR{2r%=z47WTk ע`8^G,LYйsyW`.yjii.>+4k1 oAYa|'Cǔ24Ik8!IdM-: \0/W YsUc \R,k\x4=c:0ڒjIuU#MpȐ$]>NPIO-Z3υ͝W g.f}/F up1ȇ{PrO zIF>o`S u{*] 2TNI{ȭE&ʁ`.f!fVL`jVpI^W'Q5RtTclsrF4 l<XQ?A.5l8*,dN.NJ#ՋQ>5깘 .> P1׽|r j`V)cNҊqrajFsa } %mӇ'[f,|C0z>֤I0uTL6 O:M3ghO?>}wܝMkQMta6V(ֶP’ME?MY(DwY^(DE,LSܹtqpa3fL'Srn<܏3ukkkj?9pM N `O9AHj5D4~ *5[O:wK.,L<4Mf;_.Dɜ3_~)s3 7?ijk鴭~ aTB#^F4>K#rʕJ!%_ Li\.!Ғ[Ǭ"`;;;FL&c֫"$ B]zbE?p|$Y^7mv0Vu}/L`>?ҊEkT-GžawXX^Edξy?wVǙT2g_Dykkyj,#iPhw 0h_X:Zj0P~0cH Ҿwχ8Sa!1P , $N"*QRiTO4l<< J)SM$ N׫AyߏdC>ڷ/nO`ٳLפLq8tP(pDG-ɮ罝<\x_rv4?wuE/ Fmoo䋺@pe, ""D#q 6KKK}9oƌeݾCVl/t_aT"D ,ȨB(aeeG<ćM%@v1 -ċpV٫`suهf"6>a_!j5aHb^25!<M(""' *(UUVw]ذ Q@AE\*H 5NBBBЫHϝ0y3wro&7 $<7 3dͪk |)]W͟'9*n#G  B 0+`J)|\z.c:ݡK|!b'qb<)M?nKXd8^d"6Ev녮:/|LgE*t6*'ȯdv?#x̀l>qjD%ٯn7Υexn2 K: ?DMKTʹМ>H=P Djm V _1!ekE~]cYd*PJ $+?bZNfjI;7F> Qt?Gc%lX4E|΢M񩺞`BP=map#xx5 ϟx$`qX/|pBGS6F.5Qlyu=vuka+p}M_a"[ ȶ{ _BX8P](] .1oP Ru>L(θ +sdGxTL 61%FON B\\a&;fZP,l\Ǵ).\f.bd'M; 3:Ͼ,F3&1֋H93\iYl(-Ɲ/·`q ˓VfD>*nҭ%"SoH+ c=0h8d,sb#[HέHpHmـX2+wF:1pvBPh7t^\c8lIsn WDbB%r'>ev`F <"o+wl+y=0 |15P P5Ö^mhV% nsC[\]ync~.Z/}ǜ<2Ak\b&\NTńD~'β bX Eo9j1탓P|0=ֲLdJ]t1 8V`KSȍ(Վ)v @3d#K$3LM]* +@fJGP8(bT0*pu1mXxr 83(΀Ց̀>3ng:k!ed) -AV@^>x+S|׶[!~Z/ ]*.U裏0T<*ڏ7PLD Q?Vũ8~Ȍ8Q 8;A9 kAˀJ:2j^.<#m~=V1G\@#jictx<w^  kcө*##E 謔F%(&TMQԊZ`83ofe'`F"2 428"LjC%*2Dy,lZ~ՍBKRֶWQK$[/ GP@FoN-ZrS%@1XT2;H˫" .*zـrf8!0 f,9g*Fڥ%I<窈=ђݏs^ iY5/yty%LD5 %\kVPv2F׬YsۜDC?TL \فZ^%_[D&1tKv׀l^6mIpX 0?HXCR.7Ϫ̬!yk$ՔuW?$ cbEsIgKZ/T8e`w 1wH$z'S![fkyuӚ+0^|]lʏ5@gdok013ͪ$Ԕ`&հ\eՐ `Q%X}NJ.h8c ]e )clBε HŃe*k? PLLD*λ锛izY eسe{` f(b1s2H@31ŜG, $הc%Q' U{,Zpe ƞ 3!2bʪml i8"@7X(deT:Ad"co2 Z/a\zfs"jceYydrM\¹)2 2ǖِ̓$$ mǪRa8%ꗪb2ԣCv(KB&cV( y`^||$rP .*[4f?-IkW2Ǿ{lҲ`d+?OScevJ"'z,e>$YK.$kUc]S B ,>5{LC_7=8 HYv ̬p9 1 +2xEOf`ʸ8 w Ɣ9CXXy)֋Yl3jZ2AD6,yJC 'Z2.0t$X-k̇=svp գl r=nܸ5pcΝN+% oD %h`-]>ZGXT?;^d{mK%nKZ-KzsЧ|=wʝP?V\]z3O(S Ծy1yVp;"7XD+sH >2iLda[϶0X1B2JeI}:d,b[2Oķ }[ʷ=̕ p .⃋%0jղwqn22ĬqF*M`κ)bNxT; Q NDfFȔ:`"s,g@{ykKBݩmp|dYs sȲ"JRWp\_~+}{E@qc.>.a[/ 772#[o~ƄbPоc)i]ffb;^d"*+E0-yILxlq $e2S6F@vD6BV@VdOb09$O>)BbO7$o*YdYX\cO5'$#K-W擏?IYD(e)TevVA#tR|PgTX/^Vptq.we dGĹAfLa%߬Ycb1YFfw%rטoTe>7kb6K,2`pІ*` Q* PQQT?ĩX}WWY5zltMP}^2Ε]۷d2wع<ꪫ$kBc欨X]Z->#R֋ƜQab3%=rRVE*+kԫ]Ud"*Ur$tլVafm6$ ][SP-BZ4PZ^{jz<,yZUy  9yZ0o 5`cD.Ѵ^LP*]ys8LZZZU#D醛JׄN$R7T(>/Hb8σv‹`0` U`]X!]0P$AS 5- ß [nauu(.5#3Nb t_k>Xd 2W $cE` .]c>#<Υ?ӍV<|Do cʓZ0!X* S|PQ%]heCLB&IlLƜbqs_l{,<^krXĒv< .[e@zVLH7<)q1Dz*ij)iDzQ%)/"ύ熚:>= w'-W֯_rIs 4Kqb ?>6dZUE&2sD0{FA+ȢEMT-SDco{(x<2 v{R-~pٳq|6>>Q/(?#ig(c v}LJ(H|% p 5zQPe跘e=yBPYnƓ VI8qfHint^\/D@^ȜdC"9Rk|{Ν;˘1cUnV $i\ڵk'7pê㱿DH^ey   i<߉0±19C  \|#vkx%زyE~n071! S{NEy%''̐snst=,WvKm<~c*_0YrtR駟d„ 믿)pxb vKW+kl2m4 (#FaÆȑ#+V.ҫW/*&>y7Vh"ρ%!AnZ3|Lk|M.P@G52Ǵ$Af@% V?q"ƼpZ2DAC %ns^Rpkodgg ciWH4 tH,6[$JR D`<òxb1} kӧO";f7!8& 0.#XX->5F . 5b acn 7 7SJ"@1Ãon}Yj|`$"6X( `t8q /N:ɮ]ĹE%\؎P;v,`AUQ"nf*2X.#6=:X#g͚%>|7n:y}̤:+.8?l6W\>39kmܴI>Y(DeiW§kX|Ģ~13ɔ%[^xYvU)t>t\ cqݻ9:S E%x>2Z#p~gXt ѶfCvo&\ڞŖ7zތo& `)5x[/}  -Ⱥ00n 8E Ґ“yaP:?`;0|Att@r+W1Zz<T.w/ʏ?hY vcf9K$nX1&K ֧t;V/lטZ/p 4$YF4QYU0.986.&X WPt=L3I춡ccy%.X"Z 3RTט0[4?q̊v.$Е7h 2,+Kxbs]y ~ 8]R|B{aׇkIN2E|2u#ph$$$%RPuoUݿyԝ!"!F d0_8>d 5(t/0X8,jX[-5m -8q I8JOiC(ƒz1>w5c_Oez^%D2>$X/D M[n(*wZo >W̻]0Y=OukKVw )L25F A\yvLc׿>ĚNۊc8 zkAd֐H]Pґc Ƕn4&dL VKB .,4-%6[5q1r#nF:|ʆmO[Ūo˛or1Bu1 d7d漅F|Uݸk"Iw}L/g2yd*qZ ,>`}4Ss]+2 W,TimXbOZ' nݘ.fʙqstf_"j@ŕ59g?@7+rH=/pñc͂cT'\.&` -sKSULD:QQ'QSL1YCپ Xx +L0J/<`3SsU̢JBNKꫯQ-VrUduKfO=9U]ҪjM`{?`3CBvgx3ptA K.}tja%uv.Y"c짐O Pxq(y =p,%L%.Z/I3C()DŽf&;]^}-?`Z$?B[0m@ddt'ͺ+WR)3@w'MDp0ZY[999gS P.@&%%ւZ1ҟ9s&Z]zլ^I6p|`<ck]XIY/tixbܠO17 mbȋ;-߃{ (NIX[&x Dz.F^'t)TK4\b.`TȖ.v}x"{Z4wXC7SjKs@:[zޑ@|ƬQxKxYƒSq S0glbdh43f`L3lNJs~(9Yu4B96QGn_~2&\wT Ke{zB92̶!3 2wkf;"kigubZ߾rrzz9uw0.ݍ&T?\xl  p:>S_=xv󿯀96X oa[˞ѣe;21  ,-ԑ۠X)yT]e nĄu{5fKBfX9hJԒ9rU 'H}X\d'B|nx9 ,I,kB6F2vvNH7:o/]vB[k."xEET|ŏ}x&0a3QO 괪X/EkF=!󖶔H%52OSb=ZhʕiZ` -tk+)W3hŘ]ln]R{7t^1&xåd2אחg4= ȞH8L?l1S7#C.%H9 bDXBx;ոy߿_t۶\8m,ε+5Ǵ.0`a 0 0y Sr8>Uy6ON ?tٰa;`.k) xBf:yab LwT{2Ngo [o. 21sB3tu=iM6%o+,3m>Ec_t蒚`(`/| @OT\w=ox/{hb! ӽ{uD+DR$!*qBn(|ᇮ+BJraJСC2?_ԯqۭ.jxY/L~aD2:t(6pՎǟ"+oK %&rI vfCXR` ]uI d2b1f{vV8>ƚ~]r~(،sKR Vd~;Zg^ήn,d h%.HB [ . -8 )q a.6 k$w ke`mK>6 ߳S 5=TK,āz Z0t0CaLϷ~eu+F; VAfKr Q(\?kńcpjɌ}?9dtoB$TEg/I -o bwxXݻѐx}$`2!`BK#dw^Ǥm]pO eɧ/a{]0C5dp/T<} 8סwht5/(p@,%‹y7h FLNa@qٓFJHon'̃"*^{ŔLe`֋pM Ņ 92jD*fcZ'۷] -GK=ٽ[2^dS8Y{i魢6t<*<)N3SbwՓi.+0ސgG X`:<B 8裏c!@`1]eLnٲ댌XJRB 0 s)B3(pq[zY9}36ch(I'1ݿ΂SMaEqvc:!qe3ȭ Z+77`@'}zE"z!f&26Y3*ɮ&W?5sZ!d@X)0z1ӔR*08xu3I4t)e#K[M `1Nנ*׈]d|nnx"N$do-,=N#ǴsṡЂ`a7`%d |͙M/)dLź1<х/$3m3o.bGcd! GhY01}){zieIZ1 {W; 7?f5Mŀ`zohS@gsLGWPt1=%1jf+ ǢL^r%ab> o8`ee[ $܋,k%Yuwɂ[lyXq2 $kK 1zHnzԲ` ݠp1} W1+ 5_A+`0cߥ7.1/KVXpQdt5gTw 8~@aAyg I/#9 n<iiG`ُL0FR&뻕M(H7x#cbh=Fېhk6y7TA10Od]?{AY]ߎx &QmkdRWV7=\ ǶN^.͌.l߿1a]{I'|pz 9e T[\Mts1D,>\bBx?U2&l?xT0΋U@O0k.r~NfN!'Fzᨱ%!rk#VyM/7˶ٲ~KSxE˃k-KXaAsӂ-EA畀 (" ?OpժUe .fl_ݵ[/>7]!~qBh#`7W&:{t1$t+9,oxخ&Z 8°%d !#deN\C np}x5lwt{Upu}}<`"7T|j)fPTW؂OFRT`8&tǿ8fˬw 4#8dmD's c&2ZjŴZ1 TY'Iuy7%JF!Jz1]dyg|>*KI9?5̺.Kee119x6]K&aӰ3F`f|ʦrЇnRSi;aIlG^Y'Ę 3 s'aM!`C&c`e*zВُ% iί3M=qn-fct{dtJm -hqa0lGwUh qR\` xWs` k`8y6*wޱ.鳙-GsD= 8o 3`,q!QHӟd%PËA*UIЗs ~JBdq6)8BxJ_k|ipaM%Fz=S֣eG3dYNdqFB nN#0 PBb$$`5A;i"|5!B (A0*qvFc=g4[(ҁ2y2nJz)d/:\5ȱ Ǽ0 ix%RK\b&\̸-ND,49lDŽNb1}:^pO={ZX^ rf),?djŴ,TЊL0 UhP>oaq$ڊ=1Rdq"Ƞb00l! ݯc!NXnx0٫MµN\63TXBkJ [Em_|~͍Z-y$.i,kNGB%"ulkZ?1[]kZ=.!'eݺ}M=  tdY 2>oZ~;x,+g^ m= nnyC &XĜb!d ɮ[?O4$̕7 Ӱp*~M,]csY0^o/R!GʤcdPyt R&HBƶ 0xg 6\8;,#PtyEb=<)^;kdEgd{*Xx|(k.{vW8Tى,^l2 $=xə@v1s X .0n1>qh%pLѽߠe^(te/(ͅ51{s0~?DeP--(͸FHxn8ʹnnk@*>%b? Yj #m }&l(t?Lߪ>o֬lnVW 0,]G˚Lk#%9Ɋ,I$H^ۋxr`$C?u\k+-+lYh-H /5\w,"P\wuz(:K(S [pD-[s)Q3Ra9౪xud-#x^UI;$V>`;BpRfc0tJ!LDK!T=~`Q7ޏ)u=E6m++(Ϡ@?|yuޞҸ|bafoJ_Cm=VαO]*؋To%b{e]f&,/nk@"s,.Xy ,gt9(}%H>ʛ,YE{-hs˱%fZ1cU6qU+h)|Fٜ=W*"0;vm4Saqp!ez#]NzX* gyy'5ˇ1E*5eUnApmgq~N#˚I;$me/n )N S{6S6} c1VӺIŵ҂L"k~npF"AOϟ@)-+ces\4hج#uk3CLw i)C,肙 `|X7/t$׻jU&U7hH#X]a Y^wO2ajZ1fV 3J~YYjv.Z0\'؋ֿJ͛7׻=fl{Th;WW7|ls4LeHrVGLt4YliFCA`Ŷ,0rEihLF2*|Y[$f 05OEGt B8/LO(v?2B Ftʞm],²؊_iG{!hBY/-RXL2"l8I\ bX<[, zȒs.:wG]]dBkd3WeɝJ]ot2,gJ({ZB(x .i,8 !d@2ՅqvX%,߄}mgf*ؿL3Z`8ztPT"x?\x)ٰb,=2J 8 >kk׮Ь`+`nBS.s"w>(, .XL,JMMm"j-F4<+a6za1й88#^Y &.pѺ+pa.&ϖ:g .̆Էbg5UY2N=3NQ$!~5udp,R%IWۊ8֘Yh{lFD|?G+#!d B7'$h?h|P\ܯ !"7Y[q2;%Z8:::-O؋(A%` =,f_%q3>.qRB?x<`:nh qrڇ" X;dS%7{.NffM>Rd?^^NNpm,V|+-cS~}fV`n/bIpU2%z2sCFl*{[G,;v^v2)ieţOIEI'Kz T@O G^2Z@ p?PHo 0@t{qbd4e.y[c6[ &>mx[-&\}WvX,QUy tLPz`׋Jy}#JgbXAf! m\orAM1cV+a {fт6m'`hЍf?h4q`_ ũW_;\6TYVYX151-}>B0׎QtG\-~ZE^ڗ"-pهcAVIFL( kL.H`S L;$Tޝ;[L\; 2JuAu1[f]LE0 xyal &_ sB%p眊 TjQ1/%A(`p ee7xBZ/̇o۶<}(`Y*s[r$BfGV1C @1…2BX?zhFkjcR%? ӥP3Jp1g;\# V"αwȤ$.T('acv= =qc>n7XȈ&r&.Kդ@%W0lDi.LolGl)@ŖIQzcMDkWp)~aᚵ,xfjԉ}ŗvǃ7tnp {(   %$`'`* y,X|Kcͭ1HŪ4"+/KAsFfXؐ`e>]a̧2npqrϝ 7kjTpz8̱Ζף\x.4\ )-aqa.҆ӪP'J}8j XEO)S}~xk3dgybfa/%cŀy,@qe]B,/Cp B .0 P P i]}V>=: 2I)y.<.Eq*FP㟺-O T  Vz̴CB̎cuMB*|Z Ea46?p`?kV'+B 0l$1n}9sY~߃ۥ,sFCBhV VL$e%E9ir# I* J[ nh-XCr<ոtZw$enE&`TP700bB%:`.&3aگ>TVAQB7TE VkE`vt+2@fuf55@X7m" 'j%9xRյmvsڽ69g|^vQAΛ 3"TE?]aE$0ok%*`1/d2 wWƺX a^\!ϕW^wWh6<ÄL /-OjME2qٰfPV a89>+8#=ܹba m+rZ/5hc^'<(י(OF!:L"wյ晫ѢfiK$$YcRAJ{Mh!\vz)[ec U[mY>{[%Ov1^:@]ifW%}8@`vy qL, [S<0K0yAB1s̭A;xiLmNLB>Ng,@,Dzr8'e' f:wJ2fc"V 2aINN RbY6:z 켐7<d\ve7}{2_YZ"` 6`6TT 1J"~vQxI%^lYե^\7F6%1a >`4ee!;~V GnXױo†:"TK0QDBPd2Yl oת̲ h'|Rabi=|`IDVgF?ur@nM6fc?2% e KftR-M7_:͚r1-9z̒ѹ:.qj}bk nMKZ=! *R*gm~ uq֓',!Kƍ+[=m ?o'k 5#hy@!Rّ_v?n>7n~@Z&X`vWpuƍܺAN;/)S$[`Y)W/ `Y!WSV SliY.d(|o V[od:aL'S2V L_f[f&6pu TfcurڎWmʅ)N˃|3jbY(NVn[8x c%Xf06|n33PPl/ۃkl+!~&9Ceq'<7Tc,ء,ŌônݺeyèBD,!T<[Us ʐir`ynωZ?NCqEȤ2_ʬLda2r|n2ACUSNE:l8d*!vXv NSǯ8/bNp- *NgsKlƊ չpKAɽh=16\pg-񟴸8 &7W^^0t1;6>>ֺlX&]{|`.3*ba{υ;^!KkIef91_WHy zX#V E崠8-) .Lx|"\n%ǃ <`Bf:'L( Xba*q15Wz<ı)$/Z*b,"`8\g' /;B}95۲L"pwYqK Y0S/rQ+9ufB*a/??ϖ_Y$pT3&STLΝݮ)DZ ḏMhah9ٵ&Ͷe)( rrEg8Gi]g$)LY\P6;E[Pr9MG>wyX u[O2RC"q2WQx 7]2JkӕHEͬN̕qIӾ;_,*mXw!H1+a̡" 2YjYK2>"XhɹbxL0r*kp띥}nkY.c|,7.HL>/%kJ +.TK[YSjh:֘w@K#KGNh=gfGӥ:-!*~%DnMxݪfYŚ/-s7ϋ5-">*>/(CkaN/0g/n%+Ӊ,Is喏KeKVsȫ"" 0I 2n0n#dʔ)T KHٰqߙ+SWpܶ֗>+:"LQ[:5ŔGES}hPA [ [A2POK!8(:KYsC%,-BL7`Pq|M6 }Uc]Ǿyp1A|(%2ì),<C'`^̯3gˢ,JXɔ ~ۙ `TbA<5LyvAfs0wo6ˉw:]e K@ONtG*b0a[nlFޑSou"syJ*ϫŁZ .kQQ1SC ~Ce}Pֻz؆u`c 08P_v3=SŎ *qf=^T{u-"XvIXROJO褀1ȍM|J7LȨ<B?{ޮr{n]E!UktӧMV8`XgЭcxG[ Tfk}OߧU1fZuAY&k-Y电'kW.h*† [4Ǻ.P]`*HAR`.qTpn_UD1ϻzϋiӦSr@f'ecqH7'nQk&ϲ(|xY(LSw3ZX1o~?+wDp$p˦T,a'4YN1-XSoP>*;mZA]6#)v \pXq Ǻ.pqQ Pl +\)7qljݖFCB(ª;ρ"6,8L9Ϫ? k&LǘLP(`V#`ʫX0nj*dހK5M6  [ Y ot+- 9x`ӫbNӒb5vXXr3TҒGdE~Y|)U8[*f[/]@]a^*G5@ _Y?Z{̵\.qx&] ^Z0O`m*}; X2\Ne򼅒8.ZaS(0{J;-T&:K2n2 VŻhtfCKw'-drٯUYs ϙ^MRB/$S[BeS,[ Y߷d% 0Wnu/]vPQ&fK-SWI&sI3qH(Ҟ J Ų9{^8Ȩ Z/#g/׼.&S9#KاʜCF&h'Z YDX#ߖ8_ c}t~)#Q釂SZ%Nɖ%NVɒ%Hxĉœz>X\` d{;]4\.d O;BӨQ#"`0x[2gۊ2V\h+d<3~۶^Rb_v6Yƞ9 pȜ}Wlcƻ~LH%sZ̮G~-]CYgggQyS_*<H^ E dl,,'YŔ|X%3$jic0Pgʬ~+Fӛ2#=9tu%]0 ed05J`H]H<*hɴ2,Њ!yl˞+)2ps2&[>"N@ 9 MJ 7Y!q5;1mxifm̳2@0,?K U d$Ip A0ddPyJ"H&הtY&i erJ&`8ֽn y2ߢ`F .*\c^MǍ7hiYg:3ސQ[HxD}Qrʸk\<![62丮}qֹ3ΐ;USN0s10`Ie 7lnYC!KA+PȀ(NIӵ)GTY")V$,IŵϰMO7-HuS3re`EdvDFYK*Cʲ `N9'"Ҋ0IxDG3S,l믿QYɶo۵0 2<5n2v9c[ qKUpIov]mRׯ_++V.%YٖB׻t!GzpL8(ܡ@ ((iFYHIUh{E $IeDp$KBˋ,uEfg/V_ Mp^ ^d=nMCgA0u=m̗bPRxY:VЂa?2j`[NT&pʭZW8Mtʭ֍E,CXPC2`I UR!LHYZ@PqA'$,g<g  Ғc3=,6Y]&`8CFcr6n˃L/f͚yF;̩ %0R$0f!2 z,`Ч‚Ib8;B<w4{(Xn{pթSbdTeԎ*|8ClTV'[ =8ێ(#]RRtH&l<"|V c= & 0Q5;9fGam7a4a9YЩʂX/ 002tq]XdzqhѢPԯ_ `Nk?t XD@v>b3g-8?a^k~3f0 q|~Nt:yb؆ EF˵UfMSY-T,IQRenXZ^<7d @ًY߷v h֐3ᬛ]Hoc re`ɶn28xB8 6,EvloMq\&f&?ݭc|:a無2U[ `*)`(l7Yd-[cтrm辣-݈Uipv%Ѫ})vY@- M768 Qgqmn&{̂&`L%ZSu0?+SUKՎHY2|DIe̙32ֆ ;(ʭo(6D]~* krk.**RE( wBHzBH!^B @r󟙣e6d~-݂)u l=覬:DFt>`fBQ{N]-k(ٛLFR`.$cNo&} \:"01^",((ƌ~Ĉ σLACҨ1n%NS;ЎZ:֖y^M2O4Y.{&MTCF0)U8gvDII 0HXc˵ 0%0ndS[0 S<~3*WO׃ `Yh͸Dڸr2@ `3=>lh`:b4M2uVbNMMЂ^:ת~݆QtxM +.kX$:\ʰC&Y!^Nr! `9M9y2)k^M2SGOP{FM=As)I ` tFz~ tSRZŘצMkޥaƜ[~V8v.L1π2wBއ|VܨYpV3n8_`2rH6cĺa@ h3e$ Z3j7nL˗w^Թ"F3BTw/nr}5oܲe`v%`L ,G)g]Cys#(v8GhNy#Nک24Y:Xrk#:>WeAq@F#WjwW%M&>^xmP_~;oҫG)-cSp)KG1\E!(t,Z2B2W2]iڴi $Œ"VApǀ\X8x?W89%)p+'jmߴ#!:Eu/MĤiPɝN 2(wi߲dϰ9 ru!Æi}%@gnʢM (M;YT$%uU&Lp F]HZxϘdkj-0$ C+OZ8Z>3)bu/x.  !%%6rߨe˖ɓ<%l&p4h&: fK֞hԶrn'q |M^a(.Et g0^ [ {1P6`YA q-K  'kaP0K.JZw:$+4+P|aUW--i~8|v{p\r!r4G2Ɋ7^'(ud-6;ba`xix2O{-v2/9lDHE3ldemSZJZwכ:Tk_WFI9z0_0Hrni90l@?R. 8υP(ة\\VVTuLճҮOi#)n&FKClEcTP `jR[F`ӿ &n"Q@c.zg:8do|&C 8yIo,eB.\0dάIL%d=w.kϟ%߲5Ɓ$] `x{q?Zc (1b\ n2@B-^KOclA|*v[&?b75sȺDښIQ02X:h`1F!N[r䈖PJs2*h<=dDqլYS_irt*zrffe!Sla!dEc̱F?㒹~m+`ϛ]a[=VD!oFMS*ID]֭Yq(TKCU~B)Ӕ't`iYV Es,ee:k099d.{~>} %3``qoqÄ]_>j ߛ*O7t!JI!Q@svSO=8EG%F8VQJ@!w!;1uM7ݤ&`K(50CPވ{ 0f[" /~n~isqnL4f2uQ-oJ.,_4:`0ttMNNSJSD~c] 0pY]F= W3`~3$QItxs@Ffмq'p&Q(Ј L3'fp7 \T 7p,SӐhS:e+m]IiΦ3k7Q⅋.?mdzzLp}ȰUCWT3{\`配=he(ZbzťSu?.:hW,ߝd,}/4' A~R8L;hJa`7l${,4 hCmi͐6`~5ڛ)S{s )АA_󉌌Ԇm߾{9W x/0K 4@SDS</,ᢕ-RrˉHE^ e)#'AK­`Q-"3txSu+&$X1;]q;&M[ǸOH[@l,Y*XM#1W{#}5%[̥Hctd@ + ,q 5d}2Ӏ!x'C&6PɂnukZM ={JBC$A w/^orm`_D,\K)Fg..2 \?VEXVk:DF>2 R+bdhaeϘh?ZfKWi!XZf2,3 2z ΅V?FF5\Rd؊k:d{zwvQr<[21q l25XzҌvY2x\k@a@s=V  m9ZjY_XI>rF!ĜRN'Œ<[ Y'Qb\R,2ˊYfVq31F^jpGCa㮋*^Qv1j~=#}L.b 鈣(`8kȯ-[3̩n0 ~ >#e :bbMVz9~jp`kh *,2RSShPg+d`xAo4b$E1c0<׎.6Ÿ+]kQn^RV!1P22wsgrKi9zp`=&aK&,42##q:u<ޕ:D_%`^} 0jn)_vr-ʜ4Ӕ,-cZ'3lr4Aj43eRq\^#p=I&dcLVҀ_ٴ]e;89!HjUEf@Vebɸt0h+wF pNJRb9Wp~`ӟSQZJ޼N<%SW(ʄdEJ(v\ԘʍH):ůxkk5-wvmb ^{m% 6 ^z'g,{r#gS%E سh;GY#;>.1q{ᢤŊeVh;=}& `7: ׄ2v$}SU7w ըcH@WGQz W o.k8޲OPFv({]q[̞p1Y2`?  X$)8[JږʃQ"/҆hyD+L? `.d(uR[b,xgqZ-䘡Ye  J*sz\8 @HMh##(l;Q?m@j;t1RخW'=z}GTgb\ГAif Ř0.`8,.˦{?Q!` P" op`Z\X2(ڱ=%S`mZ?twPʿ+%|>M!K_FȾ{"S]saM3F2:RIao>ʚq峸àV̱({X ` [@omdVRi]ֹsgT 2PW мߛd_wuonpsXTKF˚ d.p Ý5rPb/qç!Q]wb$5Ƶʼ5X>S2Z»qaXg=d,z=wh1E,'ӑP3`}P1z,[1XB֐i7᜴!k+ք,rLD#`XAgISV5Vu8xm&a dd L.IlD {He9YQvaO@}k-y-W4hM*?},{^S/ 9++K $_.rxVۇy|#N23K'ł9藞dNV 5.Cθ>T_f)V LNe ]abp{ݺuV)pE#=>+ix\;a\"3e QV 'QdxYeVmm ,$0DԐ cooJԚD,W\O7\sf3a29 2UVX>Q&J [=ցgLtdC ߳cil`P qڈda, f #E*{gQDO;FۤG,Y  I+W,"dU4*`4ib1tI7վц=?ž5q0ę̸̃G(#4ai,9"2Ps(ѶtzIUk|E rVyTkX/z;yE^^_J& /p\-[ZiCY0җAn5#-f>w0(?^F)n2kȠD*̸1#9ӏ^$67".FOĀ \0H6[G)M_*2r@Fê~>J9q[({6.IتLP[i]V-bWɁǫx3QN,a #qʘn{Ɯܷoj"9Wn Q<@ͅu˘{UsgoX3=YfoȨ-fdR`~n S""3QqʣG ysz=&"[wf"`{1&b+E~$'r'6-~#U6P>𗓋Ѽ..8e==90&kfG2AѧcJ?$QuL)&U̠3: ,W |ǢSDe  jժ٥R y%*\~A~aB6Й(#K5uwdC{,1`#~'MG'0yVgxNJ1.@VF 'ţ>._(+S.SXÚn/_lr4ckkXbYoW02dmJJ31Gpaݨw( 8%KMv?✗)믧_߷ozE`Ԃ@/0̶ *뀹E8J!㩜e DINV126'cr\uŕDVrT9$F+q `ky<&e_7):(4QPzq6c( X3vq哣nMd_HK7aKn+N-]O^az=,-}/z+LKM޲e %WfvtZGGh[eIC2~H EYk lԲ/0 '#J8X쑈=@SZw7a ˚saK͐!t}`f﫺0o0b3AL34{dOY%.ޯ hbgDo>J,a+ݔ=ZƢ6 Adv|\Pocr,LUrǝDLi2+Qa5pqw pZcWy΀Ǟ[,b^Ɉ9.:9j.ݦ+I) |)NТ5$E,$EP{y&:u>/1X{A1Tz뭦Teد*S>u2ӓW&-OPvebTj\{qe(iYekƋ"˗S1,ZHN]d "者xkf,_`CTIjo m `W0yqF'a^:Jq K2Jm۶g35bMdO>(9cЬp3.æӬ߼Vve-6ֺOY/5*)ɮ% I:JoYBKXd,jSL2Պ;w;E1,UU}=`

<&f&]͌,=kM\BѮ"ǥ &,HI>{eZoI1byΛM=0fƈ"_IvAZ.MV70ʍָOY/qzYtxx"*>'TenKuc _~qI&"HLkd$kfWΦ 60ڽ9Y^ (LxwΣkhZ(bZ 'NW2LҶ֋Y,S~ڸ2mj'Ufk.SZ L EU:u\ݼyֶ =\ 9 +?NniiFp,Mv:`^,X5fibC[cU֪53=6h"@p̚E1+z\kvc6u{Hxg d;=&1E#~,,DzQ;i;l 8d0seX<1 aUe 3fZ=˱yk7aͮp5\lM0PbwzŊ] Xre& ҕKa,$k^/[mߢE E5֋Kw$,=Tew!@7T}y,ɱNg|!y1gϞ%liiig_@=?`((:0eSy{(mS$L o` p~рt=$2!Gܿe 'LYB;"8A g@7( TP鎦էg}VλU;vb{טUvfhr,# M+MUʎZ,W5"UZ ׀Aiꦴ?u4|{bޖ!K"9f9<и;l&b]g _s&Yǎ-w_:C$n^X553㦵KojcyK4qE6{7>P?9mcgj6J_Ao#1e.Kg{1` گ3X,1ş :BLJbX.~盖IqE>D}}Ԧm{޽֭[Sz겪UEc f$\L u:hz54BYsvټ&Fkk'\cF:rMx`y jaj :0k5U|+s [/ ĞW|!rdWaS%-cJ"6i-b1Z,p՟qHKO M^ A\gkr$6y]43SNgMQ94Z"@ `&Wd?%]-̗_~]!DW"F'kVؾXaO4|NʀXev 7ғoN.={d+0iX=?$-ñAGtN9"h!sb !h곫y:dX0hV #9\NڼyUUI6a%Я[ծGt.@frK$oXK~O 2H2dS@IHC;k&?ޫYb2e$͜9e]pzl ~qgCae[ɘ/fD)8zj|[j}:\36fKtcI²kY}6Fґh]"X *.s(9ep7Yr;̰enДT,^n2^<l6mwy/>8b. ֋^MsN6;!2XsIIkpM1v[Jwe!]V}P660LwDK Y,mi &%uJ8E{,t4y=-:* `LenxY: ꭓsp222|2b6DNisճB.O+wvO^bU kkmm*憡>~mb3X pR|>UsK@+ M4 :Z-wvMeˉ0NJS&3P7*{,lZ_ $H?\'t)6,?9Nesf)sf.5S/-<3 ;=|ldcZ2E5u1Zp2-_^Peaa :"]+'欧>M~ܜQHk ]IXKaGyz%md4"L1ކu" ϱ}z:~x1x,;#t| `0ehF^Ks|k4ŬׅL@/7@äp+ЉyaϖژH wƎg[ ߿oBN#SjC n$tC0&44c=6tA(1[Yʌd陧 zn.]P*1ܧȊ$`ٳ)/J7 ,̙1@Ӟ! Lv1M0q<<8졇iȨc! ~TPhD.-O,ƦgBw`C x{︓*A >\L&K~SݗX_qvíʕmV8 8 ҕnӚXF{]eT\ %/,(dlIa4zEUC?`qmbiR !@X&Go]K5>]Vope HzQ,C e%ʦ#jbTd5,P:5(PQbG`yH C\qYjV9!((9܈ 'O#GE3peطſrJںu+&3,F}b<]a=tȩ ie@@S``Ư8O Q9v!Vɓ'Q05&sT ߰hrB|{~^TX V ;voQ /oݦf7/Um7ee2xְh4]IcLǤ0< BedOfH,E#2 \5c |$,rP}9oܐ DM1;*L$Zt^Tc^=2>vԃԬ~M|~'" CE-8yރAIm gu}q39s uesXm]f.w[?ّ0Z@L<63:\,e 2 gt| oXEu pX,Mpd0ٓj#Lf,k*KӖ xh]CP-nӱm=X* lgUM)q wl/mٵLݒv[2=\P l ?JG)t 3 _3#`ia鿿 `1΃Ժ|7Y"Y^,du#Du lޚraރT_]hsF 4@>+\e Pi17 ZT}!6W˰)ȣ[ke>ȬaϿloHޢGQb|zxSff Xgye69}@,< 40G)-!CäTFd:D->OL%qD!Y3u] х-`|]c63E{)o ͚5I'X3Ngaaa7q"jƙ%<{}tk据jض ghЈHcy,JI ,RP1Rry]vڨ 2ߩ_ŔE]vYjժ:q.6TgSp+iUQ^T# C ]|ās⍪z D"XEXr `x鹡klnv ܙ1͚5qѢE]@J)Tg/kuƙpj6;4l63/ȈړD)q=tes$/5d ±4b+ #GEIEh_ f  |-+M<2uהwL1C՚ n6g l|[dƔ .9֚dy[M\|mal5&Ub$wsBRц33h6 8pO'*vǪO7ҵA 6 9uOl5r=ǻnr5X36 |d>9jlr#8j@ g?@FK2e"(5i\+Y,E"c޽#޽{K/$3l8CGcW7*믿~ɔ)Snp{Z)>gܚ% iˌ=LVhS쯶EHǢ>>`f=[)ߗ㖎nrwӂ J|*hC .Sĉ=QZ!/k׮k\z^Z o"{|u܈6 K?;_nOamڵkuƙ&?sZjFy4b0pCɻD`)G& 5%t9B)` t$DULr q[R!Pq\8|hMO3g͛7=l%uiYj3FK'q'օxVDEvmX}^/vSƙ4ӬeHƙI!V,OjIYYZ4\}6:JÂ2XtI,Nsads,`1Ds7 w%~~riڹs'qFɓ'kTPٳgk1c^KK_zft]w]TAxYÿ75+b"Yi8=DJTcQ# \gm6#&` 2\a[`WՀN^vs!`/P\l`n=םju6;vzQZ!e[e$ҮťezwI&x1Ɓ[rr ~j5뢘/CLN9?J~n޼9hB~H!!!PRceCQiwiiit15*ERC,nE\}}: YuҖ8Ya X3Xʛ*ˌ3w3ƼP|A-*6lK> n9%en< r\q3XϪB9J{}Zj^oKi㌳F}ϻ3u<Ć#p~aWܰ *o讲EX,'܂EW2{(#R% -JRCCFў q&ӧOl׮4|%r{{VnQT,ۅƜq&p5LUv m\pUXdaV'X]n gܿLe6̅`1$88{EUx-ܹ= '$$e=h ̙3^bl$gJII2P seԨQvFaz+\ժUqvu,K 8ce(?s捜9Eqk(B$+];[>Dȅ\xuwn8Kq}f͚4n8 ,˖-SR4BG즁r@a ťYQaq P;v{NoٲVgشi `|fē`a8H4i  { *߾f|`+Χ}V<gr׮2gAp}rysΡ1? SNSq{.!m])oy% yo 1eam] 2k׮I"b\\M_wU*&ؠ3[q;8815]fRLӍ 7@3aLab4ruU~ܭ_6֘t܆.⬥Ç`)zg{LET u"l`c&;X]׹`fz̹FR6kT/oXL,Dq$DϨ38|^q2,X(p.LQQR.,BL(D{S6^ř:DD{)d"6 ϯDvu֘ + H Ə;bXLI䋉ݤ,++kWQDht5n8Ge.K`T%c3j|sTR"eR"&vBh )S&pkŊdZ/vd7nDBy? plq%9H@c &>V#WYﻍ|S\( h"P4(YcqΝT .JD!&&'ř4[9slێ1ϑXYYuYFFCb0h29v\dV\m18 ;3%,+W Uvj^/D37h*)B.je m۶|2L⌙#*Z ga k֬Yjm)G~>sLLD4fnR~|IF+"RLx%<%~?^I(d +ٿ :-Lwd>w9;8 mvtF۪2s%{߃Zb4L ,Lmڴi9&3w/t݊f&MĻw6i3 WЛ `)"QNQ⻇[3]zيhdBX:,O-_mg-G'/#{[@S6\ѣ 4k5lz:,č%ćUw&\F[@Ѡ`Fo:~15{EccdE4q&Zo)&.#cu'B+h|*L ɱcGޘ,2}`YFEK2XBBK,%~xڽ*JnQ@3Djen]3ԺDԀv!fL`Qϟ~[Їj}KW&Ni/rwh3lJ~1~lJ aHy9 ,SJ-`)!n.3\/9B;=VO:{9fzS~f7/$^6Ь|8}{# Ͱi N7={:ǏQ 'o'N3\">|{08jE,͡{Ry){38c\(РvƼ?Pj)2RLtBF0JkD- ]豀Fy5?toD46u6{lӂj `:IjѠGDjnHGc XFEڴۉr[p s4'?*:.O6]dbbtX S19X҉?E,}X蚶(KgM}$h̤/|„ `f>znuD6T|7@_i5&T_3#ta޺u+rZZQP."S( )`#¡ RPf^!)f 䲪Ei&6U l"_̱<]@`C#? q*.)==srr!Fo4D*'ƪwPqkk+k޺u_ r~~>O>njs-j/~W$/a/2.luoVȪ8A dhH/H݌؀2kp!50f4}JQfXr~+^ ^7c#FN}FSi'xZ:ڑ\KfkM$T!\?PE8xQJ,`iXEG{ _'gw]nJt3g=/y0oQ&>Q߷"KW A ,"(tFYdXeKBD6$0jc+mqcBIX"&2-3:Ͻ~UǢޒ$w{o:ID4)#&5hJ"Lك[q3<:>?Ԃ]h4O \G(5[(,!] O 'wHB|%si9+Awz<7S]^`_E.t} 鞒83ii?xy_,A6h\ ]Hg%g1AAށZPwP&@TYٯ9hLkQrvpfGRRtD$H~߬pAᵃPGXa4ǀX Xtdϧ=gfMud’3TjQ1ڐFw_"śPP6ƞɤcK!370J5V:28"'(5pzCin(FΪC|{gO02aΝ(myXdRC^`P))buӬT@,xBNKyN`7Je4J oPRe@>KX<,+h"hKO.i|*O 7 2 yz$D٢"1~ˣ!?pkO-<竨Q <-ax"$YM@R$\٥)ZL& ˌѨh6W5gWd|&ӵq]C-E!nevTPU'\fS-4y/yhFz6F+u BUk-%X|3!$g) 3)qti]WXdTKB\xad# pJcdN=nK>D2]lsT)3C8_gH^ʍMi>}᳌/[USdS@4l,T +RtZ\ {rct.eBi{TLq*u`o׮]QaIm۾h+za}JO8a <+T$#4BZ485p28è= 94hC]d͟;"("U~ʩ.Ȗ966cGY.}0 A;DY[!t r1{%xFjKnj@y6V^jiO:D}b:JKskClAbbJŐN2ކ쨈7ja"ާ<$n2 |I@l:; gLF%hĩBj ) %Ѫr, w^Nջw`m]OhSBQ9B x&g4RJBI@{jxR2!Aol̎\VxX\I# |< K8fN]@Pr/Mc*'0H'C{i1xe }5u.&:D']aPOB(PVykJ (.T:ȈG^j~ܾ}{V5vM_`};Xn()O^ ppf$V0:UI@$QZ@MS> 7* ^](VUKo|YN&x-MEȋ :rBGqK #;(Ex,),)y&wX`P*?CO ހN<xt|8`gٕ8t74( nuP~O@$T NF w< Cys%-TYvq tBT?33qUb9 -$FjPޥ tInizda,Tbu`zTb{׀{ UW`Oz46?-?B5Ce<~$BHN ʏєIF&6UfΥsVbc6m65a+<Bz .qCpN$qnғŠ^ӈp s4ϫèH$,A ns` wկ_*UJ~UWc"_~E"T<qcP)9| "]2p쟏{d>:VKr?#vg rF>X՜hЎgMfOq8092LH ߣb\9(wF%HI &Ll&r3ɐ_˛7#9Wxw&Η|:+D3H&מjC4nB_8p6Lf7r=ޖǓȣ* C( !QecİZB . }LsI7AADFF>YIg HS8 uy{ДH*ġ*NeP߾}_dvD0VJ86! !@V0!g[ <~vYzٳ[f¿q&%@;%qV id]tDK0vͿͤEkJz TNv0۷o_#E궍PDIV.~N8YY D0׏^q^ I0L DDs vM1 -jŎPn\/fY'%@N!= K0v:DWq ֞ 4FFE ̖a׮]L*@ksϮy9E\v#"W?~6D0(&|iX4 pi)d>.z0RW8W8oN2a\XZra{L|3a=VTBb,~v ;'L2VTW1 !}Ea5To0ORZ \TV{?22 yZ)6`A6 siƊZJ.U;e4 mlUG8*8LK˺& ^ Bŏ'A\ pows7leܝjt9tyz̎9@2EZh6=`,8.x"bαSNPjObw4àL\\\w<U r{lN"N^'s~ Epʉ"5P2_`(6lXѦ*{1ٸⶦ M?s:A:5ߌJDKG TF xlnش!n EmC^]> ñ:3T8:0p cD52iҤvT={\gA6 y!j\΅ dO$p1T!AR=:!/&SqPmܓ˷n^WO4I ` ޜHsȗ7pJQ# hXLC[ Ѐ}J*=9т QcΝM4>e+*)2<:ZD&/Xx_g2ҏ% %+ By 4>5Srs5%ca@2eB8 6p]5E7 (}f th*rUW6msaFbGŖ0ҥK뮻d6ÒZo77NV EhXYHHhiL`s@B=O@7"%="E$LN2tcNib*-]wyBn-x6sɀ9.5>gos kq1&+%Be2Hzwp~;N8 n(hT>3Rx {&;_TqwZA&<~wp<r9%ӝ;|ɋ{1lT޸LDؼ$M!J*Lwv6 t&vw7ƍfk#&L#AFR&Tɗ"dD1RpP x_վ/ rZ$$օn={CdɌ@3i0ΗK8ϋ cLׂŒg =>s3ױ; e!/P ᄆ~TGd /1sӀou2͌raf^/11q0=ރ!Vݲ&r@Z6ܶimߌs mpx B"މ2ڸq=#GgB)((rWG8Pǖ᷃^`=vVݰa/GT׮]зGN SLʐ^n<IB b1ǧ 2+-)f~a)3I70Bv١CuOnot:;a:1x=\{&$\3C"%ǒ[A#`{B ǃ@J' efFrD>nfFAGFPeDjHL1 J'cR^HSW^TPT/ϗB{ %1Lj9W{AE1":33s G FP3bGyK7oܜ=SHܰa]B/ս#%d2 ?LȊb #?ׯ_Z:fkBǏu۶mߤoϖ4 zל[sc}M|K(jD"SLm۶{% :aQEyxX*زeK0uH9D>)T^^\V!@|8pjRr3~6M!ӣG}rrΝ;FΫ;pP@[ƌ{ٱcGoZ׭}- (" ;(Ex {儺`\7|r׷[v8/J(z\<|d糤|B!$ wUD?62߄+&iξ}~@ϳo?/a#|>:6Ř̟K0"8Wyt\r{ׂ>n4σ9e~WqNr~/.쿤b^:

2024: the C++ Annotations now exist for 30 years! c++-annotations-12.5.0/celeb/celeb30.eps0000664000175000017500000123572514624365757016532 0ustar frankfrank%!PS-Adobe-3.0 EPSF-3.0 %%Creator: (ImageMagick) %%Title: (celeb25.eps) %%CreationDate: (2024-05-25T13:47:27+00:00) %%BoundingBox: -0 -0 319 174 %%HiResBoundingBox: 0 0 319 174 %%DocumentData: Clean7Bit %%LanguageLevel: 1 %%Pages: 1 %%EndComments %%BeginDefaults %%EndDefaults %%BeginProlog % % Display a color image. The image is displayed in color on % Postscript viewers or printers that support color, otherwise % it is displayed as grayscale. % /DirectClassPacket { % % Get a DirectClass packet. % % Parameters: % red. % green. % blue. % length: number of pixels minus one of this color (optional). % currentfile color_packet readhexstring pop pop compression 0 eq { /number_pixels 3 def } { currentfile byte readhexstring pop 0 get /number_pixels exch 1 add 3 mul def } ifelse 0 3 number_pixels 1 sub { pixels exch color_packet putinterval } for pixels 0 number_pixels getinterval } bind def /DirectClassImage { % % Display a DirectClass image. % systemdict /colorimage known { columns rows 8 [ columns 0 0 rows neg 0 rows ] { DirectClassPacket } false 3 colorimage } { % % No colorimage operator; convert to grayscale. % columns rows 8 [ columns 0 0 rows neg 0 rows ] { GrayDirectClassPacket } image } ifelse } bind def /GrayDirectClassPacket { % % Get a DirectClass packet; convert to grayscale. % % Parameters: % red % green % blue % length: number of pixels minus one of this color (optional). % currentfile color_packet readhexstring pop pop color_packet 0 get 0.299 mul color_packet 1 get 0.587 mul add color_packet 2 get 0.114 mul add cvi /gray_packet exch def compression 0 eq { /number_pixels 1 def } { currentfile byte readhexstring pop 0 get /number_pixels exch 1 add def } ifelse 0 1 number_pixels 1 sub { pixels exch gray_packet put } for pixels 0 number_pixels getinterval } bind def /GrayPseudoClassPacket { % % Get a PseudoClass packet; convert to grayscale. % % Parameters: % index: index into the colormap. % length: number of pixels minus one of this color (optional). % currentfile byte readhexstring pop 0 get /offset exch 3 mul def /color_packet colormap offset 3 getinterval def color_packet 0 get 0.299 mul color_packet 1 get 0.587 mul add color_packet 2 get 0.114 mul add cvi /gray_packet exch def compression 0 eq { /number_pixels 1 def } { currentfile byte readhexstring pop 0 get /number_pixels exch 1 add def } ifelse 0 1 number_pixels 1 sub { pixels exch gray_packet put } for pixels 0 number_pixels getinterval } bind def /PseudoClassPacket { % % Get a PseudoClass packet. % % Parameters: % index: index into the colormap. % length: number of pixels minus one of this color (optional). % currentfile byte readhexstring pop 0 get /offset exch 3 mul def /color_packet colormap offset 3 getinterval def compression 0 eq { /number_pixels 3 def } { currentfile byte readhexstring pop 0 get /number_pixels exch 1 add 3 mul def } ifelse 0 3 number_pixels 1 sub { pixels exch color_packet putinterval } for pixels 0 number_pixels getinterval } bind def /PseudoClassImage { % % Display a PseudoClass image. % % Parameters: % class: 0-PseudoClass or 1-Grayscale. % currentfile buffer readline pop token pop /class exch def pop class 0 gt { currentfile buffer readline pop token pop /depth exch def pop /grays columns 8 add depth sub depth mul 8 idiv string def columns rows depth [ columns 0 0 rows neg 0 rows ] { currentfile grays readhexstring pop } image } { % % Parameters: % colors: number of colors in the colormap. % colormap: red, green, blue color packets. % currentfile buffer readline pop token pop /colors exch def pop /colors colors 3 mul def /colormap colors string def currentfile colormap readhexstring pop pop systemdict /colorimage known { columns rows 8 [ columns 0 0 rows neg 0 rows ] { PseudoClassPacket } false 3 colorimage } { % % No colorimage operator; convert to grayscale. % columns rows 8 [ columns 0 0 rows neg 0 rows ] { GrayPseudoClassPacket } image } ifelse } ifelse } bind def /DisplayImage { % % Display a DirectClass or PseudoClass image. % % Parameters: % x & y translation. % x & y scale. % label pointsize. % image label. % image columns & rows. % class: 0-DirectClass or 1-PseudoClass. % compression: 0-none or 1-RunlengthEncoded. % hex color packets. % gsave /buffer 512 string def /byte 1 string def /color_packet 3 string def /pixels 768 string def currentfile buffer readline pop token pop /x exch def token pop /y exch def pop x y translate currentfile buffer readline pop token pop /x exch def token pop /y exch def pop currentfile buffer readline pop token pop /pointsize exch def pop x y scale currentfile buffer readline pop token pop /columns exch def token pop /rows exch def pop currentfile buffer readline pop token pop /class exch def pop currentfile buffer readline pop token pop /compression exch def pop class 0 gt { PseudoClassImage } { DirectClassImage } ifelse grestore } bind def %%EndProlog %%Page: 1 1 %%PageBoundingBox: 0 0 319 174 userdict begin DisplayImage 0 0 319 174 12 319 174 0 0 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000100000200000300000200000200000100000100000201030504000000000000000000000000 0000000000000001000001000001000002010001000709080202020303030C0C0C000000010000 010000030000030000030000030000040000030000010000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000002000002000002000002000002000002000104000104000104000002 0503040300000602000C08050400000A0501100B050400000801000E0700080000100700070000 070000160E030600000600000F090B0E08080400000901000F0705060100050000030000090804 11110F0002000A1010000302000608000304000507000404000202000606000102000102050706 010302000000000000010000010000010000010000030000010000000100000200000100000100 000100000100000100000100000100000100000100000100000100000100000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000100000200000300000200000200000100 000201000100000100000000000000000000000000000000000000000000000100000100000201 000100050706000000010101020202000000010000010000030000030000030000030000030000 030000010000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000002000002000002 0000020001030102040002050001040001040000020100001511100B0704030000090400040000 0400000A05000902000600000A01000E06000C04000E06000700000A01000A0200060000060000 1A12100800000600000902000F0A04110C080300000100000E100D000100000302000607050D0F 000202000102000102000203000405000002000100000201000000000000010000010000010000 010000030000010000000100000200000100000100000100000100000100000100000100000100 000100000100000100000100000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000100000100000200000100000100010302010302000000000000000000000000010000 010000010000000000000000000000010101000000000000030303010000030102010000050304 010000010000010000010000010000010000010000010000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000002000002000103010204010204000103000103 000000120E0D0400000400000A05020601000803002E272159524C8F88808F887E635A51393126 140C010D05000800001109003E352E584F4A9A918C675E57201710120902655C53070000070000 17120C191611000100000100070B0A000200000102000100000100000100000100040605000000 000000020202000000000000010000010000010000010000010000000000000100000100000100 000100000100000100000100000100000100000100000100000100000100000100000100000100 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000100000302000302000302000201 000201000201010101000000000000000000010000010000010000010000010000010000010000 0100000200010200010100000503040100000B090A010000010000010000010000010000010000 010000010000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000002000002000002000002000103000201000002000000080401332E2B66615E76716D837E7A AEA9A3A19A945049412F281E666054898176DBD3C6C7BFB25D5548160C000D030008000022180E 281B1261554980746814080063574BC8BCB01F150B0700000C05000400001B1A150E0F0A000000 070705010000070604080607010000010000020001010000050304010000010000010000010000 010000010000010000000000000100000100000100000100000100000100000100000100000100 000100000100000100000100000100000100000100000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000201010302020403000000000000000000010101050505010000010000 0100000100000300000300000300000300000300000300000400010300000C0809050102030000 090506010000010000010000010000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000020202030301 0200010100001F1B18312C28241C191A130D2B241E2F28203B322B61584F736A61130B00665C52 B1A79BFFFDF1B5AC9DA79B8D4C40325F5242504333C3B3A4504030281707A08F7F1100005C4C3C B5A8981F13050800000C0300060000040000070400030000040000060000140B0C060000040000 080202030000050100030000010000010002000002000002000002000002000002000100000100 000100000100000100000100000100000100000100000100000100000100000100000100000100 000100000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000010101040404020001020001020001040001040001050001050001050001 040000060002040000030000272324030000070304030000010000010000010000010000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000303030101000100000302000706040807030804030501000400000F08020E0701060000 0600000A03000800000700004A4237ACA497645A4E281F109E9586F9F0DF8C8072B1A493877865 7D6D5694826EB09E8845301B3F2A15AE9984130100A4927E6655431808002214071003001B1108 1910093E3530180D0B0800001005030A0000070000100605060000040000040000030000010002 000002000002000002000002000002000100000100000000000100000100000100000100000100 000100000100000100000100000100000100000100000100000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000010000010000010000010000010000010000010000010000010000010000010000010000 010000010000010000010000010000010000010000030200080705090806050402010000020100 0201000400000500000500000700000700000700000600000B02050600000400004C4648090305 1F1B1C030000030000030000010000010000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 0100000100000100000100000100000100000100000100000504020201000300000501000A0603 0C09040A05020601001D16102D241D685F58746B642D241D1209004C423980766C261C10251C0D A19587695D4D0A00004A3F2DF8EBDBA99A87C6B69D6B5A3E89755CA79378998469594429877257 C9B39BBCA68FE0CBB63825140E00001808000B00000A0000897C7473645F1503000B0000110200 0A0000120705070000070000040000030000010000010000000002000002000004000002000000 000000010000000000000000000000000000000000000100000100000100000100000100000100 000100000100000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000010000010000010000010000010000 010000010000010000010000010000010000010000010000010000010000010000070302040000 0400000905041612111615130A0907010000020100040000050000070000070000080000090000 0800000600000D04070600000A0104676163130D0F373334080405030000030000010000010000 010000000000010000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000010000010000010000010000010000010000 0100000100000501000300000300000400000904000B06000A02000600000D04004B4239867D76 B3AAA1D1C8BFB5ADA26F655B41372BA198899B8F7F201404B8AD9B8D82700B00003C2F1EBEAF9A 756448C1AE8E7C674ABBA687C1AA8BE8D1B2C9B293FAE2C66B5138FFEFD789735E1100004E3D2B 5343332C1C0F221205D3C1B734211A0E00001504000F00001304000A00000E0402060000040000 030000010000010000000002000004000002010000010000010000010000010000000000000000 000000000000000100000100000100000100000100000100000100000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000010101000000000000000000000000 0101010000000503040100000100000B090A010000010000030102010000010000010000030102 0100000100001311120100000602030400000600000700000400001E1A195C5857010000070604 0A06050300000B05051D1415473B3D0800002314170D01030A01040400000600023C3638403A3C 060002554F510400000F0B0C030000100C0D030000030000070506030000030102000000000000 000000000000020202030303000000000000010101000000000000000000000000010101000000 0000000807050100000403010100000E0A0703000015110E211D1A3A353237322E312C28201913 0D06000D06000D04000700000F06000800001006000C02001A10065D5347B6AA9EAB9F91392D1D 4F4231E0D3C24E412EA99C8981725D0D0000372710A59274756140DAC3A4836C4CCDB495AE9576 C8AF90E3CAAB876C4F91775CE5CDB52E1801513C277C6A56BFAC9D2C190A9C8679856F62160000 0F00001A060018070022130C2316100E0300170D0B0400000A0605070506000000000002020204 020001030000030000050304010000010000030102000000000000000000000100000100000100 000100000100000100000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000030303050505040404000000000000000000050304070506010000010000 02000102000101000001000001000008060701000001000003010201000001000003000013090A 0E0405100607060000150F0F5955540400000100000300000802020D04052C22235A4B4E0B0000 3B2B2E37282B0600000500010C06082B2527272123130D0F5852540E080A030000090506030000 2822240D07090400000903050D090A010000030303060606000000000000000000030303080808 0000000000000303030303030303030202020202020101010100000100000B0A080F0E0C221E1B 18141126221F2C27234E49454F4842635C567A716A7A716A685F56453A3421170E1A10062B2115 170D030800000800000A00001206004B3F2FA598875C4F3C4C3F2CC9BDA76A5B46B9AA955A4B36 0E0000584527C0AC8BBBA786CFB898A08768C8B08EB99F7E7E6443FFEBCD4F3618F0D8BE533D25 2B1500C5B09BDECCB8BDA895634C3AB7A090260F00220C001F09001400006C5B51A3958C0B0000 1409050C04010C0704030000010000080607040203120E0F080405030000030000030000010000 020001080607000000000000000100000100000100000100000100000100000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000020202060606020202 0000000000000404040100000C0809050102030000070304050102030000060203030000070304 03000003000009050603000003000007010315090B4E40401004041B111009010058535016120F 0A0603040000130E0B0600002C20206858591502044A36385646490600000602030A0607151112 120E0F2E2A2B4F494B0B0507040000110B0D0C06084C434610070A0600003D34370E080A030102 050505030303000000000000020202030303000000000000010101030303020202000000000000 0000000000000D0C0A0A09070C0B090100000400000300000400000500000C0500070000070000 473D346C6259796F65978A82B5A89F5E5246473B2D72665A817567261A0C0B00001A0D000B0000 1000009C8D7A988976221300B4A38FD6C6AFB1A18A37270D1504009D8A6AA18C6DDCC8A7A58E6E A08969BCA482CAB290ECD3B4C0A7897C6448C3AE931A0400BFAB93CBB9A1FBE7CF644B35C9B09A 32190312000086715E5744338E7C6E7C6C5F36281DB8ABA31E130D07000018100D0C0704040000 0400000400000400000400000500010E080A050102010000010000000000000000000100000100 000100000100000100000100000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000505050000000000000000000000000000000A0A0A202020030000030000040001 0501020501020300000300000804050400010300000602030300000300000D090A030000100708 0A0000352526493B3B080000190F0E20181615100D0300000400001109070700001B0F0F615152 2C181A412B2E5F4C4E0400000100000100000604050B0708403C3D342E300400000701030E0508 4A414441363A07000013070B716569060000030000000000020202010101020202030303000000 000000020202000000000000000000000000000000000000020202010000010000080705080703 0A06030502000500000600000700003229206E645B7A706666595062554C6E6158716559938779 94887A594D3F695D4DA39686988B7A342716160900130400100100C3B49FC2B39C291902BAAA91 FFF5DC7D6D530E00001B0A00BAA7899F8A6DF4DFC0755E3E8C7555B49D7D6E5536FBE4C4C2AB8C A48F7219050088775DC9B89EFFEED5AB9377D0B69B8B7359392107927C646E5944988672362515 5E4E3FD8CABF1A0D05160B050700000A0000160E0B30282612090A150C0F090003040000040000 040000030000050304010000000000000100000100000100000100000100000100000100000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000030303000000000000000000 0202020505051919193333332E2A2B070304030000090506030000030000090506030000030000 1410110300000C08090300000703040300000B02031303061A07096858590F01010F05041C1412 0803000904010601000600000700000F01014633353F292C351C20604D4F090305000000000000 0202020100002F2B2C120C0E0400000C03060B000454494D1C10140A000047383D55444A080000 040001030303060606050505000000000000000000050505000000000000000000010101060606 0505050303030505050908060A09070804010703000400000500000B0300110A041C130C110700 1104001104000C00001E10054B3D326C5E51716356B2A595C8BBABA699896B5B4C887868A99989 BAAB9861503C0E00000E0000B5A58CCDBBA3291800C6B59BFFF7DD45351C0E000099896FB6A58B C1AD92BAA588887354BAA685B69F7FB6A281F3DEBFAA95784633153D2C10AA997DF5E4C6EAD3B3 D7BF9DE3CCACE9D2B39C876A847057C1AD9534220E4C3B2B9E8E7F1605001A0C030A0000080000 443935A79C9A0700000A00030700000600000500010B0507060203010000010000000000000100 000100000100000100000200000100000100000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000030303000000000000030303010101000000090909181617575354221E1F 0300000300000300000804050B0708030000030000302C2D030000110D0E040001030000130F10 0600001D0D0E4A3638402D2F453737080000251D1B3E3634130E0B0400000600001107060A0000 1F0B0D462D3134191E5440420804030002010103020103020000000D0B0C0300000E080A060000 0E030721151913040919080E6552580D0000190A0F383435131313000000000000030303000000 000000020202040404000000000000050505070707000000000000000000010000010000030000 0703000400000601000B04001B120B41372E4B41387A6D649B8F837C6E633C2E211707000D0000 0D0000372A1AB2A595FFFDECD0C0B05A4B385E4F3CBCAD98EEDEC7BEAE97413118241400CAB99F B5A48A2B1A00F7E7CEB6A7902617023D2E17D7C7AE9F8E74B09C81412E103E290A8C7758B8A483 FFEACBE5D2B23D2C0E2B1C008E7F62AE9E7DC9B290A8906AA58F6ADBC4A2DDC8A97B6649AA967D 1F0B00715E4DCDBCAC1C0A000D00002819120A000081726D8A7C7B3A2E301B10140B0004090002 060000090305080405030000010000000000000000000100000100000100000200000100000100 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000020202030303030303 0101010000000000000000000100003A36373F393B1C16180400000802040A0406070103181214 191315332D2F262022080204100A0C040000140E100700001300023E2A2B433131312121150A08 060000746C69040000110C080600001005030B00000E000051383B4A2D31342022060201010504 000403000201000000040203030000110B0D0600000E02060A000039282E2C191F432E350E0000 4B3A40443E401111110000000000000909090404040909091B1B1B090909030303000000020202 0000000000000303031212120B0A081C1B193935326E6A67716C686E6965615A546D645D564C43 443A3130231A302217645349AB9B8EBBA99D9383742C1F0F0B00000D0000574737D7C7B7FFFDEA EEDDCBA79682D6C6AFE8D8C1BCAA925F4D350F0000DFCEB486755954442BFFFBE86B5E4D0B0000 3B2C17B9A990B09F857665492E1B00210E00483515F6E3C3FFF3D27969480E00005A4B2CE3D3B2 D1BB94B09970A48E67867049FFECC97E694AA69277453118D2C0ACB4A3911705001707000D0000 281912B7A5A1271815C0B4B655494D14090D0B00040600000400000B07080A0607010000000000 000000000100000100000100000200000100000100000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000010000010000010000000000 000000000000000000000000000000000000000000000000000000040404060606050304030000 4D47493632330300000B0708050102040000352C2F3A3134251A1E655A5E070000180F121E181A 0400000900010A00000F00006D5F5F2519190700001A100F5B5351120A08302826180E0D090000 0F01010D0000624E505F494C170406060201020403000100000000141412100F0D030000050000 0A010207000011020565545A2B181E0E000038212B74636B0F090B000000000000101010040404 0000001D1B1C595758090708020001010000010000010000060503262523484745636260585753 4D4C4865615E4C49443E3933312A24473E374C433A554B4281746B93857A584A3F1C0C00342417 736354AD9E8B7E6F5C6B5A4841301C453420857460E0D0B9E7D7C0C3B39AFFF3DAFFEED4E6D5BB 847359301F03B8A78B4A3A20998A75FFFDEA3728130E000057472EE1D0B6665539271400342103 110000907D5FECDBBDAE9D81200F007B6B51DFCEB0DEC8A39E875EC3AD86836D48DAC6A3A4906F 998467180400F4E0C865533F0F00001402000E000091807694837B776861AA9F9D241A19070000 150C0D0F0609040000070304030002010002010002000002000002000100000100000100000100 000100000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000100000100000100000100000000000000010000010000010000010000010000010000000000 000000000000010000030000030000030000010000000000000000000100000100000100090B0A 0000000000000B090A060405010000060203030000201C1D3F3D3E110F100000000907080D0709 453A3E6B5C611201071E0B110C0001190D11645B5E050102070506050100171312464040352F2F 06000008000044383A1A0E101F10136455580800000800000C0002261A1C54484A544A4B050001 0300000400000C0805514E4917140F0603000601000600000700002D1F1F49393C3A272D38232C 41293631202A0903070100000C0A0B2A28293A38390F0D0E6D6968120E0D0804030501000A0605 0703002D2727443F3C3B3633302C29060702040500000100010000080702030000040000110A02 0600000700001006004A3E3285796DD2C4B9AFA196605041513F2B7C6850AD9981937F67826E56 907C639F8B72D5C4AAB6A5896B5A3EF6E5C9AC9B7DA69778DFD0B19788699483652A1900D4C0A7 8E7A61220E00110000D2BFA1BFAC8E281300170200705B40846E56AE9A82C7B29D3A25124D3827 3A240FDEC7A8A18965CCB59377603ED0B999BCA7889F8A6D311D02D1BDA437250D0F00002C1B07 2A1907B09F8F645444BEB1A1362E230F0B020400000A0501040000100C0D090408010004010004 010004000004000004000002000002000100000100000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000100000100000100000100000100000000000000 010000010000010000010000010000010000000000000000000000000000030000030000030000 0100000000000001000001000001000001000204030808080000000100000100000A0607090506 090506050304181617050505010302040404040000352A2E6E5D632E19206049510D00000A0000 5A5154323031000000040605000000222021242021040000070000180C101102072A1B20615257 0E02060900020A00031A11143E383A413B3D0400000600020A0102201B188B8682070200040000 0803000F08020600002E22226D616354434917060E0B000410000A0400020806070D0B0C535152 0300005955561814130F0B0A04000016101004000019110F1F1715271F1D2C24211A1511070602 080A050405000203000706010A07020C0701141007463F37776E656F655C4E443A41342B483C30 66584DA9998AE1CCB79F89718D775F927C646E593E69543999856AB6A287FEEDD1B6A5879E8D71 FFF4D6847556807152B4A586D2C1A3614E30422F11F8E3C8A59274432E11715E40FFFADD412D12 2914008B775EE4CEB9CEB9A6A891833822152008002A1303947C60D4BB9CAA93737D6647927B5C 857053A99477503C218672591000002A1802C5B39D867561705F4B52432EB0A3920A0300090500 0C0800040000100B07030000030002010004010004010005000005000004000002000002000100 000100000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000100000100000100000100000100000100000100000000000000000000000000000000000000 000000000000000100000000010000010000010000000000000000000100000100000100020605 0001000202020606060100000B0708150F110400000B0708010000080607000000020403030303 030000180D1156454B38252B402B320D00000B0001281F22302E2F0303030202020000000F0D0E 0D090A04000011080B0700000800001F131742363A150A0E0600000400000703041D191A201C1D 0A0106060000070000372E2F7B73710600001008050A02000700000700002C2422473E3F2B2225 0A01060600040400040300020300000F0B0C201C1D0A0406140E100701010600000B0203060000 160E0C090000070000160C0B554B49140F0B010000000100010000040300100D08322F2A5A554F 6A665D3F38302219101107000C020021140B2619101E10050D00002E190478624A9781696C563E A59178CAB69D5F4B32301C03837258EBDABEAC9B818F7E62EBDCBF8C7D60817157918167DAC9AF 37260A6D59409A896DC1AD928F7E62D5C1A6BEAD9337230A2D1B03432E1BBBA897A79183453224 1400001701005C442AECD5B6998263775F436B56397A654AB19C8159452C3F2B130F00009C8A74 E8D7C37C6B593C2B198A7B682A1D0C110800070000070000181107090200130E0A0400000A0607 030002010004000004000004000002000002000100000100000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000100000100000100000100000100 000100000100000100000000000100000000000000000000000000000100000100000000000000 000000000100000100000100000100000100050908000100000000040203050102120C0E241E20 241E200400000300000C0A0B0000000001000707070300000600002C1D224F3C420D00000D0000 1D11150600000B090A060606010101040203030000040001040000191013090003070000090002 170C100E05080400000300000100000503040402030B02070700020700025C515533292A2F2524 2E24230600000600000F0A071B15150703020100000707091213170000020300000E0A0B040000 0400000600020400000802020600000600000C02031006051F1514372D2C6B6160170C0A0F0704 110D0A01000011100C32312D4A4742514E4938332D0A0300160D061007002D231A2B2118483B32 7F7269C3B5AABFAFA0634E39271100240E00604A324B371E523E25A490779E8A72200E0086745C FDEBD344321A0E0000B0A087C1B19A7A6A5366563DA191781D0B0065553C5A492FCCBCA29A8870 F5E5CC2614000E00000F00002A1909DCC9BB503E321804001704003B250EB9A4878F775D4C371C 442E1678644B948068412F17110000110000BFAE9CA695835847373726166959490B0000120500 453929958C7D1C12080700001B120D0C0401070101040000030002010002000002000002000002 000100000100000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000100000100000100000100000100000100000100000100000100000100000100 000100000100000100000100000100000100000100000100000100000100000100000100000200 0001000305040000000100000300000400002920236B62650D0709040001030102000000000100 07070704020306000011050958474D2A171D0B000015090D0900030402030000000202021B191A 030000070304050001130D0F201A1C0D0407070001040000030000020001010000000000040404 000002040004060004140A1264595F170C1250444825191B070000090001040000020100010300 0001000003000005040004040100000D070910070A0600000600001F1619060000070000090000 0D01036458586054546559592E22220C00000700000400000300000F0B081713100D08041F1A16 4B443E605953211811695E58978A827A6D657D6F6672645B9C8E83D4C4B5D5C0ABB09A825E4A31 170300412D15533F272F1D0569574195836D3F2D1764533FE0CFBB4A39270E0000645542CDBEAB 7E6F5A6455404E3E273B2C152E1E074C3D26CEBEA7D9CAB371604C1203001D0C000D00009C8A80 88776F1300001705001B060077634A654F3739250C2511006C58406C5742241200160300160500 A695857E6D5D18080067574829190A110100665744DACBB8C6B9A8685B4B43372BDACDC56E635F 070000040000030000010000000002000002000002000002000002000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000100000100000100 000100000100000100000100000100000100000100000100000100000100000100000100000100 0001000001000001000001000001000002000002000001000507060100000400010B0507060000 0C0105493E4241383B120C0E0100000101010204030002010200010500010D010524151A726167 1000050800000A04060808080000000100004240411814150300000400002B2527504A4C0A0607 0C080903000001000010101000000000010005070601020401000406010809040B231C23160B13 2F242A0800000F05060E0405040000010000040905040D0A000400000502000504090708060000 0600000C03060C03060700000D0304070000180C0E9286885A4E4E3F33332214140B00001C0E0D 5D52504E46443A36352E2926282320221D191D15120B04000700001207010800000A0000160900 42342B5749407A6C619E8E7FD6C1ACCDB79FA18D747F6B523F2B133F2A155F4D370F0000210F00 8976654E3D2D534232AB998B3321130D00001E0E00C7B7A78679683C2D1A3C2F1C2516031A0D00 70614EBDB09DBCAD9A695C4B1D0D0022140727160EA0918A0E000014030010000063513B39240F 6F5D476C57448C7A665946350F00001706003321137563552614083D2D209A8A7D190800312112 CFBDA942301A493824C9B8A6C2B2A374665B4C3F370C0100070000050000040000020001010103 000103000103000103000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000100000100000100000100000200000200000200 000200000200000100000100000100000100000100000100000200000200000200000200000200 0002000001000001000100000804030E080807000007000007000042373B160D10030000090909 0305040001000301020300000C010512030874656A1B0C11090002040000010101090909010000 3C38392824250300000300002D292A534F500402030604050000000202022D2F2E000201000100 02060500010200000502050A0000050100040A030A06000207000211060A0700000B0205040001 000100000301000A060009050008050E0A0B090002070000382D310700000800001B0F110D0103 68595C87787B3527270E00002D1D1E3D2D2E8B7B7B6052515147466D686579716F6F6765766E6B 8076746F6661584D49453A341A0D051407001F12090B00000B00001E1005302011715F49D5C1A8 E9D5BDA08C745F4D3733210B1C0A002E1B0A200F00221002705E52311F13402F2588776D26150B 221107241609AA9E90A093831B0F000B00001106000D00005C513F847766C5B9A99D8F820A0000 1405005F524C1304001506001503005948362C19088E7D6BC7B4A59B8A7A3A29190E00000E0000 4F3D313C2C1F1C0B01D1C0B67362580D00008A786A5C4732220C00816D55D1BFAB5443310F0000 0D00000D0000080000070000040000020100010101010103000105000103000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000010000010000010000 000000000000000100000100000200000200000200000200000200000100000100000100000100 000000000100000100000100000100000200000100000100010300000000070302080202060000 0C0203190D0F0800000B00030600000300000606060001000001000D0D0D0300000A0104493D41 584C501E121614090D0300000000000101010A08090300000602030400010A06070100001B191A 0806070000000606060E100F4E504F0E100F000100040605000102000204020A0D00000505060A 0503080500050E050A070002070000090003060002030102030504000200000300000403040000 0700006055593E333708000053474B3024260800004C3D404D3E413123236658588F7F80867677 776767574948392F2D655D5A5F55543B312F4D43417B706C877C787E736D968981A2958C81746B 665A4E382A1F1A0C010B00001202000F00002E1A026F5B43CAB5A0B19F8953412D362312241102 1806001301001806004E3D3336251D2918104C3B3315070016090008000084786C544B3C190D00 0B02000A00001B1201564A3C312819DED2C6544A400A00003F342E2618150D00000D00003B2B1C 342214685849D1BFB16656490E00001F0F021A08004E3D336A594FBEADA3CFBEB6211008413028 69574B1500003F270DAE988045311964523E72614F1B0B00120600090000070000050000020100 020001010103000105000103000002000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000020202040404030303000000000000000000030303000000000000000000000000 000000000000000000010000080405040000040000060203000000000201000100000100000200 000200000201000100000100000201000000000000030200010000060503000000040402010300 070705000000050503010000030000070101060000180E0F3125272516191D0E13190E12040000 05030400010002060500010001000004000022171B615559251A1E170E11030000010101020403 0503040400010D0B0C010000050304010000010000050505000000060606131313616161020202 0B0D0C000000060A090009080003040106090004050000020503060400020E050A0A0005070002 0E05082E282A030000110F10000000010000060000766B6F3F343807000022161A52464A0A0000 0800000A000046373A6F61615B4D4D0C00002515161303030C0000080000170E090800000F0400 22171340332D493C3663564E77686181736A86786D85776A82746776685B5B4D404232224C3B27 6E5C4664523C8F7D67C7B5A1C0AD9C5C4B393322121100001A08000D00000D00003928213A2B24 1203001F10090A00000A01000E0400726A5F342A200A0200080000150E00180E021C1407584E44 BBB2A90900002A211C281D1B1005000D00002113061101007F7164E6D6C91709001A09000D0000 36251B4F3E36CEBDB5FFF9F15C4B441A090272615A0E00002F1904725A407F6951F4E0C8EEDCC6 73624E0E0000170B000B01000A0300080300100F0B010000010103040509000002000002000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000010101030303020202000000 0000000000000202020000000000000000000000000000000000000000000100000900030D0206 060000080204030102040404000100000100030706000301000100000201000201000000010101 0705060400000400000A04040905040E0A090100000100000A09070100000B07060E0808100708 1208090800002011146455584A3B4032262A0B02050D0B0C0001000105040001000101010C0809 060000271C2043383C4F494B030000000100010302040203030000090708010000151314313131 0202020000000202020505050B0B0B2E2C2D010000030102010000000000000100000200030504 0001000909090100000300020500030A010611080D372C304D4246060000060000060000100708 11060A4A3F430B0004150A0E0F04080D010508000014080A6354574A3B3E1204040A00000B0000 1B0B0C0B0000120403190B080A00000A00000A00000A00000A0000190A0326180F44362D918378 D7C9BCDED1C1C0B3A3AC9F8FAB9E8EB2A390A4937F56442E412F1952402C554231685544907F6F 9684768472663121140D00000D00001A0B042B1C151E0F081104001207010D0400070000191007 564D440700000700000700000800000700001A11089289802219122118131D13110800000A0000 1F13071103007A6E62BCAEA30F01001406000C000010020086786FAA99918978701C0B043E2D26 1D0C051F0D01503B26947E66FFEBD399856D8F7D673D2C18AB9C89C4B8A87A70640D0600040000 0300000C0B09060606000002020305000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000010101010101000000000000000000010101000000000000000000 00000000000000000000000003000023171B3B2C31080000060000030000020001000100000403 0307060001000001000002010101010100000300000A04060C0203080000070000060000060000 090401110C09050100060200050000040000060000281E1D574B4B5143432011140F0004110509 06000001000000010003090701050401030207050604000006000022191C3F393B0503040C0E0D 0001000202020100000907080402031717174F4F4F050505000100000000020202050304030000 0400000802040E050807000004000016110D302B28040000110D0C030000030000030000060004 0400022F262B4B40460800000B00030A00000800000F0408140B0E0600001A11140600000D0206 261C1D4238394F43450F03050800001D11110A00000A00000C00000A00000A00000A0000190A03 2D1F16675950786A5F5E4D4367574A5040334E3E2F4737284F3F2F766656A59683B4A592A99A85 A99884A2907C7765514835246655434433233624164A382AA59588C4B4A7A5948A3224190B0000 1103001A0C03190C040800001B120B2D241D251C13231A11110900160E03100800140C011B1308 07000030271E544B440700000B02001209020F05000900000F0200786E6472655C0A00002B1E15 0F020033251C584A4164564D2A1C1324130B24130B0D00003321156B5643A4907844301857452F D0BEA8DDCEB99487744C40309D9485070100130F060B08010100000000000F0F11000002000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000101010000000000000000000000000000000000000000000300002B1A20 5B484E100005080000060000040001000000000201000100000100000201030303040203040001 0400000700000A00000F0000130304100202221616332928281E1D080000211917120A08110907 0700000800001307075244446D5F5F17060C0B0001060000010000000201030907000100000100 0100000905060701030400000A06070301021214130001000000000100000A08090000000A0A0A 2B2B2B0103020606060000000402030300000400000E05080D02060B00030B00000F000045302B 5F4C480D00000B00000901000B0505030000040203010002211C20413B3F0C010514080C100003 0A00000700000400001910130E05080C0306554C4F332A2B2B21220700000800000800002D2121 4D41412115150D00001709064B3D34150700827167B8A79D95847A5343363C2C1F4A3A2B3F2F20 3A2A1A2B1B0B1506000D000011020024150032230E62513D503D2C746150A99685BEAD9D988777 A18F81C4B2A469594C4131247A6C5FAA9C916A5C511B0D020B0000130600433832716863635A55 716861AFA69D3E352C0700000700000700000F07000700000B02001B120B070000180F0A070000 0C03000D05000D03006F655B483E340A00001003000A00003D2F2644362D21130A1F11082B1A12 301F171605003A2A1D463322372511C8B7A3FDECD8B09F8B8E7F6C0A00000800000D0600060000 0905000400000E0A07020100010000000002000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000010101010101010101010101000000000000 0000000000000000000000000000000400001D0A10624B53240F160C0001100509090305010000 0000000001000406050606060100000300000A04060B0205080000331E231800030F00000E0000 1401032C1E1E5648488175755349485B51502F25240C02011A0E0E1307071406063D2F2F4F3E44 14050A0600000100000B0D0C000402000200000403000000010000120C0E040000080405010101 0001000002010000000402030101010000000909090001000303030808080100000B0708060000 0700000E02060B00000D00001A00041F00005023205B3331220300110000100100070000060503 0507060608073A3B3D49494B0A06070600000900000B00010A0104030000110B0D0400001A1416 565052120C0C0600000600000D03043E3433483E3D1006050700003429273F342E59483E6E5E51 857367332113301E104C3B2B5140306453417465527667528576619788718E7F68685A4045371D 35260F2615032413031100001E0D004635258877679080707F6F5FBDAD9ECABAABA79A8A908275 B4A89A94887A382C1E2A1E12564B450900000D0200170C063A3027C2B8AF31271D594F43574D41 0800003A3026988E84271D14190F060800000D0400070000130C02070000473E35251D120C0400 0800001F150B3E31281104000C0000493B32FFFCF19A8C811D0C02261609766657D1C1B1F1E2CF 2C1F0C140700382D1B0E03005B5241403929282214040000090500030000070302100C0D010000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000020202040404030303020202000000000000000000000000000000000000000000040000 341F26785D664730380D00000C0002060000060203010000000000040404030102030000040000 0800020B00040B00007B606555383D290C1120070B1000000F00001000012416165648485F5353 3327270700000800000C00000A00000D00002A171B25141A31262A010000000100000503000200 0105040507060100000C0809030000030102090909000100000403000000020202000000000000 1113120001000505050100000300000A04060700000E02060C000110000312000346212853181A 521011531918421210210000140000070000040300000400030C09303938363C3C090909010000 0600000F06070501020B07080300000501020B05070802041A14142A2424090001261D1E443C3A 625857918786BFB5B4BAB0AECEC3BDC5B4AA928072A69486A392829584749C8B799988768D7C68 6B5C4760513A5C4D3662543A6A5C427E7055AD9F84DCCEB4E6D5C39988785D4C3C4938280E0000 2B1A0A4C3C2C514131908071AD9D8EB1A494968978AFA393E0D5C3D7CCBAC1B5A73D322C080000 180D0913080208000043392FC9BFB57F7569655B4FABA195685E54B2A89EA79D94080000130802 0D02000E0700060000322B218F887E170F040D05001309001E140A2E21181003001E100784766D C4B6AB8B7D721D0C02CDBCB2F2E4D79387771003000D01001409006D6552CDC5B2ABA4929F9989 BFB9AB2E2A1E0400000B0803080401030000030102010000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000020202000000000000010101040404060606050505030303000000 000000000000000000000000000000000000060000432C3480626C694F580E00000B0000070000 0A04060604050101010000000100000D090A10070A0700000800000E00008A6D725A3A3F180000 1400001100001903051C0A0A2616162A1C1B0800000800001A0F0D190E0C080000080000140606 0D000035242A5E53570C0A0B000100030907000502000200000201040203040001030000010000 0406050105040001000000000202020000000001000A0C0B000100000000010000030000070001 0800000E00040D00001801092F141D663B4271242A5E080B6E2224581A1B3206051400000B0000 0100000003000004000814120E1A180C1210060A090100000301020100000907080100000D0B0C 030000030000423E3D64605F6E68685B5555827D7A8C848269615F847C7A554D4A4E433D7A6A5D 978475998677A3907FBDAC9AD5C4B0DCCBB7FEEED7F8E8D1EEDEC5D7C9AFB8AA8F94866B6E6043 4F41243D2F144F3E2CA08E80AC9A8C806E606151424D3D2E4333235C4C3C483B2A5B4E3D423524 150800302513584D395D523E776B5BC5B8B2897B7A1507040A00001508001104002E21182F2317 0F030082766AD3C7BB32251C675A524F423A0A00001005000F08000F0B00979086FCF5EB373125 090300090100140C011A1004080000382C2031251943352A4F4136534238827469908478594F43 1A0E02342B1C847B6A6C65532922100E0900060000352F21262216120E05080300040000080403 010000010000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000010000010000010000000000000000 000000000100000100000100000100000000000000010000010000030000030000070103040001 0300000400010903050D04070D02060B0102060000040000000000000100000100000100010000 070000230A1066474D7A5D621500001502040800000804030000000608070100020D04092E2226 3120261202050A000015010299767A5C33391F00002A0A0D1500001000001F0B0C5644445F4F4F 6959593626260B00000D00000B0000160704564646130306080000241B1E030000010101010302 0001000608070100000907080300000E0C0D050505000100000403000501000000080705040402 0000000001000C0E0D0001000204030100000400000A00030A00000E000012000034161E5E2F37 58090E58000384383A5111122700001500001C0E0B010000000501000400000B06010D09101B17 0C120E000100040402050102030000140F13120E0F0C0809312D2E4D4948332F2E353130070200 0A05021109060600003B312F08000032251D58463855402F1E09001300000F0000221000291703 33210B4A382264543D827259998B71B7A98FCDBFA4C2B499A89A806E5D4B2B190B2210021A0A00 2414053C2F1F5F52423A2D1D1104000B00001A0D002D200F1E11001407000E01001105000B0000 7D72709B908C2217130800000F040008000032281F1F150C080000BFB5ABA0968C09000032281F 0F050010060006000040392F9C958BD2C9C03F372C0C0400160E03A2988E53493F1A1006120800 0800001A1007291F1652453D09000043393041372D1C1208554B3F281F100C0500100900130C00 635C4C8A8476B7B0A6A29E9578736D17120E0300000F0E0C010000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000010000040000060000040000010000000000000100000200000200000200000200000100 0100000300000600000700000800000B000014050C0700001C10141101044932384B2C34150000 1700031000030100000002000005030001000E080C0D00021400006F4D4C8F6B6B2C0D0A140000 0B00000104000005000005050301060B0004482E3952343C1100000D0000200D06B08687633236 1D00003B191A7157584C38391503030D0000150103473133836A6D553B3C180000130000482F2B 4F3C380700000804030B07060300000F0B0A0802020802020600000600000B0505080403050402 0000000106020B110D00020003000018100D040000030200000100010703000200040A08000100 0000000400000800001300021700021800004013184F0E126923256022234612141C0000200305 0B0000080300030502000300000400000400020C044D544C0005000708030400000B0207180E16 322C301D181C0A06070302004847453B3A36030000050000090200281F1A4D423C6C5F596F5E56 5A44366D53426E57455F4836553E2C5039273D2815261100200B000F00001704001302001A0900 36251151422D8879669C8B7B9D8C7C8171625444353F3124271B0F0E020020130A1104000A0000 0F02000F01002214092111040D0000180A000D02000900003E3432857B793A302F1D1312241A19 0700000A0000150C07322922ADA49D2C231A2219100800000F0700170F04322A1F1C14099E948A 140A0008000033291FEBE1D7584E450800000E05000A02000C0704231D1D0602010B0603372E29 382F26150B02080000110700281E12483E325E544861574B6A60563D342B433C34908B85ABA6A2 0300000A0907010000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000010000060000070000040000030000 0000000001000002000002000002000002000001000100000300000600000700000800000C0004 1E12160800000B00005A43492F121769464D26030A1200000F0000090504000200060C0A000002 09040A1B0C11381C1B63403C916B684A27211200000D03000003000004000003020200060F0005 4B2937603C46150000130200331F14BC908F59272A2800001B00001700005945466B5B5C201011 0F000012000026090DA385874C2C2D1500008164601C0702120A080100000300001B1515060000 07000015090B2E22240E0405060000070101030000000000000100000200070803211A14362B27 39312E030000010300030905000300000300090F0D0000000903031004040F00001400002B080C 260000491215652D2E6D3B3C4C22231700000F0000190D0D030000000000000400161C18000300 050A0444494235382F010000150C0F07000421171F403A3E030002151112545351555450282723 423F3A4D48425B524D8B807A7E716B7E6F688E7C72A89183B29887A58B7A937968937968957E6E 947D6D937E6D846F5E6E5B4A4431222716062B1A0A4736266555456D5D4D6B5A4A7D6C5C5A4A3B 70635374665B72665AA39990857B725D534A544A410B00000A00000E00000D0000210F050B0000 0800000D05031B13115149475148496C63647B72755F5657150D0B0600000600006C655D2F2820 1C150B1E180C0D07000A0200130B00261C12473D330A0000150800392C23493C330E04000C0100 140A080B0301090506110F120402050100000C0401070000080000231910473A3141342B271A11 1104000C00000C0200080000130C04060000928D895E5A57010000010000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000010000040000040000040000030000000000000100000100000100000100000100 000100000000010000010000030000010000000201383A372A21220B0000361D215A4043371E21 6B57580A00000D05030400000B0706010000070709000004150F1158403E5B3A358E66646D4A44 1400001003000002000004000003020100040F00054624326A444F160000120000432F24BD9595 885B5E7F58595032321200001606061406060B00000E00001A01051400008B6D6F4426264F312F 7153510F00000800000A040611080B362D3022171B0800000D010565595D352A2E0700000E0508 0400000804052422230101010300000E03013D2F2E776D6B0A05020605030002000004030A0E0D 0001000300000800001B080A1F02061800002500022A00002A00003C13113714123113113B2625 0F01000600000A0907000100050A06282A27292A250706021A17124A45411008060600020B040B 120C10342F331D181C1917183837353736324A4643322F2A37322C5B524D5247413D302A72635C 756359B19B8DCDB6A6CEB7A7B9A292A68F7F937D6F998375B8A596CCB9AAE8D7C7DFCEBEE4D3C3 CDBBAD9383746151421B0B000E00001000000D00000B00001C0E0313070010060021170E584E45 5A5047786B63584B431403000D00001A08000B0000372C28453D3A221A180F0705060000060000 170E0F332A2B2018160C04011F1714060000352E26100900150F03060000120B01070000180F06 07000008000020160C2A1D140A00001006001F140E0B02000600000400000300000301020D0908 160F090F06001C12092D231A1F12090C00000B0000110300130600080000080000160F07150D0A 312C28686461010000010000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000010000030000030000030000 010000010000000000000000010101000100000100000100000100000100000100000000000100 0009011C231C66635E1308060D00005A4544432E2D6E5C5A322723090100030000010000000000 07080A000004040000543C3A69474588605E845F591800000E0000030400000600000303040005 110007411F2D6C474F180000110000503A2FB18E8C1C00002404056E54554C3A3A170908080000 1B0D0D11000021080C4E31363C1D222204069175741E02011300001102050A0003483C4074686C 6D61651D11150800000700001E13170600000C0306060000130D0F4640422A26270D04050B0000 47393983777719110F0B07060000000001000606060C0A0B6A61623B2B2C1100002D0D103E1519 44151B2800002300001700001100001A08044B403E5A5552060503080A070408071D1F1E090909 312D2C0600001208075749492F2323060002302B2F0E090D353334615F602625230A0907201F1B 0300000E09050600001E15107669638C7D7882716A715E577E685B614B3D361F11331D0F5E483A 776455897668A79686B2A092AE9D8DA59385C2B2A3DBCBBCDCCCBDDECEBFCFBFB0B9A898594838 4838293427170B00000A0000100600170D0408000008000032251D70635B9A89816E5D5526140A 493830372C281C14110600000600001A11121007080600000D04050E0604060000060000060000 060000060000080200140D030700000A03000D06001108000E05000D03001A0D0482756CBDB3AA 544A410800000800001A12100701010400000500000600001C130C4D433A5A50472B1E152B1E15 483A2F74665B5E514864574E1E140B0700000600002E2925423E3B12110D010000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000010000010000010000010000010000020001020001030102010002 0100020000020000020001020001020002020002000308010002002B3125585A4F0801001E0F0A 7B5F5E3A1C1C6850500F01000B0C07000300000B0700020219141A0A0000311716805D5B865D5B 89605E2403000F000003000000050000030403000412000743212F6C444D1F000016000061493F B89695411E221600001601002A1C1B2F23230700000800001300040F00007E6166210207472A2C 7A5D5F1200001A04060D00001C0B110A00000B00016C6064473B3F0D02061F1619060000090003 0F06090600000600001A11141F141808000010010438292C3F33350E0506110D0E020001060405 010000040000362A2C0E00001400003912172E0106440F1557292C1F06020A00000D0400040000 11100B595B5664696500020035393A5254530B090A1F16172E22245A4A4B907C7E59464A090003 0D0B0E0100022626262F2F2F050503100F0D0706020C090404000017100A61585381746E463732 25140D76635C735F546B584A735D509F8C7EC7B4A6A492845B493D311F11251307150500150500 0B00000B00002416093325184F3F30645343998878938374B2A595A99B90766A5E8F857C968C83 AEA49BB3A9A093867E6F625A41302854433BAA988EA4938B3126201209040C02001006040F0504 0700000700001006070800000700001208060C0300180F083229209B93886F685E9B9690434039 0400000B04000F060010070030261CC7BDB3B9ACA3362C23080000120904110803090100100806 241C1A655C578D847DD0C6BDF1E7DEDACDC4F1E3D8E1D3C8E0D2C7DFD1C6B5A89FBAB0A72D241D 060000231E1A201C19010000010000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000100000000 000000010000040001050102060002060002040002030002010002000002000102000202000302 000200070300080200010200656356453B310F0000563331633B3C6D4B4C3722210201000C160E 0004000002020F050D0F00041300007F5D5B8D6160865A59340E0B170000060000000100000203 0300041200074D2C376941493A13142F13087B6057AD8F8D56393B75605F6351511509094E4443 6C626318090C0D0000482F3565484D1500008C6F733117181800001C06080E00000D00000B0000 14050A180C1023181C06000004000008020405000104000012090C0A0104070000080000080000 0A000018090C070000060000090506030102070506050304120C0C372B2B3F292C4426283C1518 3E10134F181D2500000D0000100D06010000000100010600050B077C8582151E1B131919222325 0300000600003E2F322E1B1F51383E2C191D10070A1111112525252A2A280F0F0D0304002D2C28 130F0C0D0A05322D297F76717166622F221C4839346F5E579D8C85A59389917F73907C73A08E82 A6948899897C8E7C7088786B938376928275A294879183769A8C7FA29487584A3D2215054C3A2C 5544345B4B3C6356465A4C41796D61A49A917E746B4A40377A7067998C8470635B54433B8D7C74 8573690D00001D120C0700000D04000700000700000C02011006070700000E0403110705070000 0700001A110A8D847B8A8277C3BCB2DCD9D24C4B46040100040000090200160D043B312752483E 190C030A00001309001005000800000F0601271D1B372F2C130A03423930837970ADA097A5978C B0A2974E403510020065574C9185796A5D559990870C0300150E08040000090502010000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000001000002000002000000000100000400010600020900030A0003 0600020600020300020100020000020002020003020001001102001100001E0A0019030080635B 330C072A00008F5D5E643A3C6C4E4E0800002A2B2614181708090B06000415040C11000062403E 9A6E6D895B5B471F1D3E221E0A0000000100000201040002100003593541633A40552B2C48261D 8E70666F53521100001C0A0A5C4E4E4E44433E34333A302F1F11111000008E757934171C2B0C12 84676C18000152393C3E282B1300031502081000051A0B10070000080002231D1F4C4849141011 030000030000080204140B0E170C1012060A13070B0900000F03050C03060400000E0C0F060709 0001000000001511100700002612145A3D3F563234421518441014380E100E000012130E000100 1D231F222B260003003D4844555E5B0004020001000402030A01043125290B0000130004201013 0400000B0B092A2A281C1C1A11100E0100000F0B08050200110C083A322F423934544945685B55 7869646A585486756E3928201B0A0026130C4130264332283C2E232F1E140F010013050043352A 5F51444133263123165446397F7164998C7C8C7A6C6756463525160D00003F312662564A231910 0800000B01000E04000A00000B00005F4E465A49410E00003F2E26170D042B221B635A53514843 392F2D1A100E0D03020C0201130908070000130907070000352C25281F162C24198F887E272621 0706011615100F0C050902000700002A201608000025190D5A4D4440332A0A0000100600302720 3128210B02002419132A201720130B1306001002004B3D321B0B0011010013050093877B50433B 756C632B221D0600001A1511030000010000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000100000200 0002000001000200010501020800020B00030C0004080000070000060000040000010000000000 0001000400001200001C00002300002900006727289C5C5D2C00005F2C2B6B4142846261321517 240E107161640900020400040D040713000043211FA6787A916161592D2C664442190A050C0904 0101010400020F0002603C4660333A643636562E2696746B5E4241230D0F0B0000130707362C2B 5E54536357572B1B1C2D171A785D621700008162684A2D32290E137F6669695557584549140407 46373C55494B1C111512090A635D5F65616025212206020116121304000004000012090A070000 0B01020D0304060000120C0E060405343537383C3D060C0A0408070101000702000A00000F0000 2C0C0D3F17183507093912131408080000000001005055511218161019160005023D4643090F0D 01050406060603000009000216070C200F15392A2F0B0706000100222220262521201F1B0B0704 0F0A06070200080000070000170C08796B687F706B7F706B806E6A614F4B82716A6F5E5688776F 96857D72645B67594E6C5E5357493E6B5D526153482B1D101406000B00000D000027190C1F0F00 1F0E005E4D3D7B6B5CADA090B2A49985796D847A71786E6550463D2C221922150D493C3437261E 14030046342A705F55796F65584F465D544D4D443D605752372D2B0C02010E0403070000534947 645B564C433E1F160F0700008C837A211A1001000010110B010000030000070300150E04362C22 251B11564A3ED3C7BB877A71160900080000140A012B221B120902090000140A000C00000A0000 0B000047392E1202001606000B000053453A51443B4D433A1C130C0801000B0300030000010000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 01010102020200000000000000000001030200010000040306080701010104000010070A382C2E 5C4D500B00001606090F00030A00000900000700000600001002001200002F00004D0000710512 7F0C1DB34F5B601E1F2E010086655E714E4C6F3A422700008A5663280911080A09040A060B0000 33110FB38587834F517040405731304835310A02000706040600001000015F3A426132386E3C3D 4E2219B58F864F33322C181A1E0E0E0A00000800000C01002313131400016B51544C2D322F0C12 88686D1500008F75781E080B2612147868693628281B0C0F41353543393A7169672F292916110E 746E6E1813100400001C17141D171745403D2F2627060000060000130E0B0804030202000A0E0D 010A074F5A56141D1A0002000C0D0829211F35262328100E1F00005F3938614142342528221E1F 0D0B0C000000090B0A0001000002002E34302A302C0106020507040807050C0809281F22070000 554C4D100C092C2B26605F5B33302B35302C07020028201D070000241915584A478D7F7CAB9C99 9B8C8762504C83716D93817D6859520B00003627201F11080B00007F71683F31265F514657493C 2B1D103123164032255F4F40867667918172A79788B5A494B1A0909A8A7B544737110300120600 1D130A0800000E04000B0100291C142B1E1633221A8F7E76C9B7AD948379A69990968C827A7067 3D322C1106020B0000100503241917655A585A4F4D615652594E4A0E03003F342E5E544B060000 080800070802010000080500110D04060000140A001006001206003B2F238B7F730E0100120800 291F160700000D04000A00000F020031231A63554A99887EA69689B7A79AA39386A292856E6055 130600372D24070000070000110A04040000010000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000010101010101000000000000050505050505000201 0F131200010000010001010108020407000012060837272A877476321E200F00001D0709311B1D 230D0F110000120000270500531311740613960E24AC2138951C2DB566692300005F3A326D413E A7616B4300055E1A29754A530000000005001407011B00009F6E719E676A7D4649572D2E604846 0700000C08070E05081000015A353D57262A7542415A281FAC817A3315154731336B5959625252 2818180B00001300001B01028E70721B0000553135532E353F20255A40431802050F0000190909 302221180A09180A09736564574948080000140907584D4B3C312F1B110F1C12106058553E3633 5B565218130F0600000C070424201D000000000200161F1C232F2B4B575309140E00020013120E 2119163425222C141235171512000018080B3930350B0509090506050304191B181C1E1B555A54 5459550002000002000505030403013430310903054B45452A25221916112B2622322A27271D1B 0700006A5F5D7769687667645546438273705846443927230D00001C0A0643312D4C3D365A4B44 64554E3B2D2496887F94867B9D8F8496887B85776A716356B3A396FFF2E3EFDFD09C8C7C7C6A5C A190807E6D5D7160503828190C00001305001105000900001A1007100600090000120500362921 56453D46352D2E1C122B1A101E12060800000A0000080000170C06231814130806524745342927 080000150A062B201C10050060554F31271E0D04000805000101001818100300000600001B1308 0C02001D13070A00004D4135796D61120800190F06382F263C332C4F463F80766D3C2F265E5045 3B2D223F2F2248382B1101003121143D2D207D6D605C4E430A0000241A1107000006000016110D 010000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 04040402020200000000000006060604040400000000000201020408090B09070A030000060000 0800001404055D494A8D7575573B3A1600003F1D1C653E3F3F18192400003B0804631717861320 9F162A900017870618B65B606B27262700008D53528E434A772734320000895C613329270E0F07 0B0000170000865558AC71758B505458272A7559560A00000400000F06070F00005F3A415A292C 945C5B844D46C3928B7D5B5A573D40220C0E3E2A293521201B06031200005131325F3B3D1C0000 9D747859323777575A321819543E404836360B000015070428191652403E6955540F0000220A0A 281010624D4C4833324F3B3A15060309000030272289827C615A54170E09312725736E6A22211D 070C06000300121E1A0D1C1734403C0006000002000C0B070A00001B0C0925100F250F111E0D13 2619203C3137130A0D04000002010015141028292380827D4546400001000504000602003B3736 181212534B494A423F0900000800005B504C87797681726FA997953B29272915140E0000634F4E 6654525745431F0D0B625350B5A6A191827BBFB0A982746B61534A51433A180A00342319130300 2D1D105A4A3B6856484332221504002211005C493A7160508D7C6C402F1F2818092518080B0000 0A00001006000800000800001107003A2D255D504866554D65544C69574D67564C45372C33271B 25180F190C040B00000A00000A00001507041B0D0CA59796A294915C4E4B50433D3528220A0000 0700000F0C03010100030000171308524C40B4AC9F6C62560B02002A1E12594D41342A201E140A 665C539E958EB4ABA6B8AFA8958B82D9CCC34C3E331103000D00002515084634265A483A47372A 2F1F124F413670635A1107000700000A0300040000010000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000010101010101000000000000010101020202010101 000002000004040308010005010002050102130D0D1206060B0000110000664A49A3807E6E4543 2D00005721217F47485D21204403014A0000770F187E05147000007F071378131BC771743A0000 9D57596D25299D585D2A00005D31328F77754634300F00002304026D3B3EA76A6F93555A531F23 80615F110200050000140B0C0F0000654145532124884E4C80453DA9746E653E3F614345140000 1200001700001400001600008E68672200006D41429063668F666A6B494A46292B4E3938342220 493A351F0E07311E18B9A09C2608061800002200001B00005C3536D3B1B07C5D5B130000422F29 281B134F463D61574E20110C2819147D726E110906090A04121711626D674A56523D4C4704100C 080E0C3B3D3A0400000700000B00004030314A3B421E111A50434A453A3E060000100B08030000 0401004949419B98910E0B04040000060000221A182319184236367163600A00002213107B6967 6652512C1817766160533E3D270F0F412C2B6A55546B57567462605F4D4B70615E23140F291A13 3F31280B000025170C1C0E037161549A8A7D8F7F70C2B0A2DECDBDC9B8A8B19E8DA3907FB19F8B C0AB988D7A696756464B3A2A29190A1A0D00211308271B0F31271E42382F473D3472685F968981 7F726A53423A3D2C242210060D00000B00000C00000A00001003000F02001C0F094C3E3B5F514E CCBEBD7B6D6C11030030221F4538321508021306000800000400001D1B0F120E03908A7E645C4F BAB2A5CBC2B31A11020A00003A30241A1006160D041D140D27201A5F5852B9B2AC9B918862564A 96887D130500251508201003433123635143948477A7978AA29489D2C5BC4B4138170E07120904 0D0804010000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 01010100000000000005050505050500000000000009090B060409010004010004020003010000 0300000700001A0C09190100180000603733AF7C798D504F400000550909A6585867181B450000 3700004A00007A20226D0A0F80151DAA3F47A8444C782628935653895C564621192502009B7172 754D4D3216151B00004B171BB5767E99585E51181E916F6E1100000B030112090A0F0000745054 5F2B2D834746884940996059825657A885896B4B4C371816160000371611421C197E5251220000 9767674F1E21A07475644040896B6B230E0D0D000043302A432F288468649C7977582C2D3C0A0D 26000062292F854C52602C30A6787A36100F4E312D48342D47393026150D523934472E29816C67 0B00000600002B2A26272C2869746E333F3B08130F2A3330585A59403E3F1D1415160C0D564A4C 4D42480D030B473E43241B1E312C29040000130E08090500060000928B836156500C0000100100 1303034C3A3A3422226A56550E0000513C3967524F4F3735412726614746120000150000553B3A 7661607A66653A28260D00001102001B0C0782736C9B8A82BAA9A1DFCEC4EFDED4C2B0A4A9978B A39183BCA99A9B88775E4B3A4A3522392411331E0949331E36210E2916054F3E2E706051887B6B A89A8FC1B5A9BFB5ACB4AAA1BBB1A8CFC5BC9E9189685B5368574F47362E210F052F1E14281A0D 1D1103190D000A0000493C346E615B4E403D968885180A092416151103001103000D0000342721 0C0000100600090300060000585246B5ADA0090100413829AEA2942014061A1004251B0F080000 0700000801000A05000805004F4A44776D647F716689786EB6A699C1AFA37260522D1B0D281608 0E00000D0000524439867970CFC5BC2E251C070000060000010000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000050505000000000000010101000000000000 0000000100020300040400060D080E0B090C0907080804010800000A00001100001F0000220000 713632DF9896A65250550000832929AE60604000002E0000270000460500A453527D141B780610 D2676F600A0B98615A6B493D73594C1800008451507844467B5C5A1600002A0000C8878FA66068 591E24A47D7E0F00000600000700000F00007854587440428F524FA3635A93574F7A4C4E411A1D 2A06062603012A07036E4943845855461612410E0D6B3837713F3E754747835D5C6F514F291411 1B0804120000785D547956525024219962656426297F3840AA616852091236000046090E370504 461E1C391C143E2A213721162F0E095734306245411600003C2D2A120A070001004E5450151E1B 0A13103E44442B2F305B595C231D1F41383B60575A221C203B363A151112363231534F4C211C16 140D050F06000800004B3E36BAA9A22C1915110000120000765C5F4026279A82801500004C3231 7B61606A4E4D5A3C3C6547474729293E20206E52516E56564732314B37367F706D827471BAADA7 9F90899C8B8185746A5B4B3E503E324B392B87756767544564514075604D816C59957F6AAB9580 CEB8A1ECD6BFE3CDB8ECD9C8CCBBABBEAE9F96897960524764584C5E544B20160D2C22192F251C 1306000A00000D00000D00000E00001B0B00433626362A1A0A0000291D11392C2352453D8B7E78 0C00000F01001F11100A0000190B08978A8452453F0A00000E04001008000701007D75683C3525 0800005950416E62540C00000800000F0500080000060000040000100D0801000017120E080000 0B00001909000D0000554335EBD9CBFFFBED9C8A7C3321131D0D000D0000170B0052453DA89E95 312821100903010000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000303030303030000000000000505051111110C0C0C01000208010909020A030004010002 1E1C1D43423E322D270A00001100001900002E00004D0C0691403DE38583CC6465550000803C39 9B6A631C000039150729000056110CAF4F516A0005953034812D2D5420156F4E3F7E6254351309 6F3835764040886665311210270000B4717AB871796F32399F7879240F0E0B01000900000F0000 6C484A7C4548935351AF6C6471322B8D5B5C1D0000240000451D1D69403E683C397444402E0000 87514F6A32319E68686333336D45452A0B0945302D43302A553C35906F662600005E2B28844347 BF7479A4515B7C252E660E1A6A1920580F16501414390907613C341B00004E3227380F0B6E423F 4D27242A0B086A55520C00001F1A172B2B29000302171D1D35393C141519504E53070105140B10 180F142F2D304D4D4F43434336373257565144413A322B210A0000180A01130000AF9892654946 1600001B0000734F53512E328F7171371B183E201E7F615F75565490716F6E4E4F2B0B0C3C1C1D 7759598A70718C7776AC98977A6B682E201D72655F3F31280D0000190700978579BAA69BBAA799 C4B1A3B9A3958D78676F5846765F4D967D69BFA690E4CCB4EFD7BFF0DAC3A693829D8C7C6D5D4E 493C2C4E40353A2E22160C031107000800000800000D0000150800200F074D3C3473615768584B 4437274D4131392D1F120600594C4374675F1407010E0100180A070A0000130502786A67877A74 0A000021140E0800000700004D46346158490800002F23139C90807E7262170B000900000E0400 0F06000C05000502000C0B0601000003000023191043352A5545388171644D3B2D7462547E6B5C FFF8E9B3A1930D0000200F051509000A000030261D7E756E0D0600010000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000100000100000100000100030504000201000000171717 3D3D3B3C3B391F1B1C0700040900060500030100000103001E1F194D464073625B381B131D0000 3600004F0C064F00009E4443DD7979A74C4B3C00008D5E569672662E0D00250000270000712726 994749520203A05C59220000835F536A463A9B6E685215148C4E4F683E3F6B44452F0001844B51 C3828883484E8F6567442A290C04010C040114000072484A976161B87B78E09B9485443E794947 2700002D00003A0807965E5D8448479F6261955553D09390A267636D36338C59564518155C3331 8562606F4C489E797162352F945A588C4849A3575BEA959CAA4F588A2934BC58649939447A272F 661F23270000643933866159431C154918135C2925582B26623D376C504C74625E5C52502C2825 1D1D1B3133321010121715184F494D1F14180B000114080C4A444438373556555135322D040000 70696141372E180A0115020012000080635FB795944B2425451B1F6C3F446B3E43956D6E512929 2F0707A47C7C835B5B896263532C2D23000042201FC8A8A9AD91905F454458403E0F000032201E A998915A483EB7A398D2BFB1938072A18E80B3A091534031170400412E1D73614DC7B29FCFBAA5 C2AD98C7B39BAB95809984718877675040313C2C1D3D2D202214091004001104000A00000D0000 21140B3F3029786A61B2A199A8958E76645A5E4C40726253584B3A4538288375686C5E53140700 1609030E00000B00000E03010E03017D746F100702180F0A0700000F0600282015706959070000 231A0B3B3223908778B8AEA20E04000F0700070000060000110C060E0B0606050113120E19160F 0800001A0D00150800413124928177C3B2A898877D7A6A5DE2D2C58072650B0000140800100600 110600857A783E3634010000000000000000000000000000000000000000000000000000000000 010000010000010000010000010000010000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000010000010000000000000000000100000100 00020000020000020000020000020000010002020013120E36322F574D4C6E5B5F2D1A1E040000 0002000003000002000D0200361D188A6260703D3A3400003200003B0000530C08964B46D68B86 742D27400000AC766CA070663A0E051D000022000080554F4C231F6A413D562F2A5328227C4946 925655924A4D924B4F581D1FA575751B00005E3835CE9C9F9763677D4B4E502E2D040000060200 1B00007C4948723F3B834A43D18C87995854774C461F00003502006A2A2AB06164AC5659751C20 BE6A6ABB716EA96862B17670AA706C501612DFA3A25616168A4A4A612821460700732322B85E60 DE8388A1454AC26369D7737B8E202D7C101D81212C8F404536000034010077413FB57B79743933 682F287E4C45663E365D3F374A362D5B51484541383837323E3D3856514E1B11102818191F090B 341A1D341B1E342522271C183B302A71645E4A3D3744352E83706A331E19150000160000320E0E F1C9CA76494C4113164B1A1E855056A3686C86494E4B1014A36B6E976365B18083693D3E4A2021 7C5655AB87877253516A4B49624442644644A88C8BAC908C8A6F64BAA3938972623B2615685342 6A59473A2917AFA08DE9DCC9FDF0DDD6C9B6837663746552473825392919493929322215302013 3626190D000026150B1302000D000034231976655D86756B7E6B645E4C423B291F3B271E5E4A41 7460554431224835266A584A6351451504001708011B0E080C01000900000F0705322D2A120E0B 0302000100000E0F090100002C281F0600000F0800110A020600003C352D7B746C090200080100 0A050005000003000015110E030000080401767267655D461F13000F02000A00000A00002A1C19 766865C2B7B18E847AA59C8D5A514208000012070108000062555C7C7179050004010101000000 010101030102030102010000010000010000010000030000030000030000030000030000030000 010000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 010000030000030000010000000000000100000100000200000200000200000200030500070803 02010003000004000007000016080873656571696717120E04000019120A210F0B120000260000 784B489A62614E1211490C093C00004C0D0894514BD88F8967201A3C0000AF7871A77A74290400 1D0000270E077D645F34171386605D390B0B8F54568C474A863B40B66B706B292B8953533E1D18 3E211BC69A9B905C607B42485A32320A08000401003F13108F55537A4841A36C65E19C97C3827E 956A63260000420B08944A4BD2777CB75459740F13B2545599484596514AA4655C763B33D79690 9852506E1E1FA654565B0C085D0907761819DD7A7DA54247BD5A5FF08D928B232C881C298F2330 AE4D56C36C725D1216722E2FAE676BB56F717E3B358F5049773E3743140C4D281F462B2229170D 180B03372E273F38323A2F2B4839362C171643272682626360404140282438251F503B366F5A55 4A35304F3733866D69604441311210482625340C0D9C6F72C69599643136410C12AD7278BB757D 884147591419D49397C58A8ED69FA26F3F3F2600008961619E7877A17E7CBC99973F1B1B593535 D3AFAF9E7D788B6D627A5F4E260B007E67578671607E6D5BCCBDAAEBDECDE6DBC988806D574F3C 473E2D5246367A6E5E998D7D786C5E4032272E20150B00001F0E040D00002A190F806F65837167 4B392F2F1D13402C234A362D614D447C685F513D341B07004731236E59483C291B2210042D1B11 170801291A150F04000C0200514C492A262502010008090407090400010010110B110C06120902 1209020600000B04003E3731756E680702000F0A060400000601000300001915123F3B38231F1C 0400009B9176756A4C0C01002D2115110604120606080000231A15C4BCB1A49C8F9E9787191104 190E0808000024141F2D212D030002000000000000000000020001020001010000010000030000 030000030000030000040000040000040000030000010000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000010000040000040000040000030000010000 0000000001000001000507040001000100000300000400000600000B01000E09050B100A000100 3B2B2B896F7267474A1700001100001200001B0801140000542B27A56F6D8D4D4E884647480808 320000A15C57BA757051120B420B049D6E6899726B1800001700006C4D4A694745673D3E5A2A2A 7B4042904E50853D41A860648A4548642C2B73504A240600C19393986164753A3E683F3D0A0700 0600006F4340A86C6B804B45AB746DBC7772A7636072453F3E160E5A201EBE7475DA7F84A9464B A84347CC6E6E9B4A46BF79718D4D43763A30F5B2AA732C28A1504F62080A5F0000791017C9696D 7E1E22C25D65CF656FC85D6789212C8D2E36BC63699C414AA94E57BC5C68AA4D58802D3592464A 914746CF8A8587484336000042150F502B25180000260F0953403A23110D4A37332A15123A201F 5133315735342F0D0C795C588C736E694D495A3E3A432723755955947773A68784805D5B2D0505 1F0000835255FFCDD0743D4241080EAA6B73A25C64B06B706C2A2ED29497D99EA0B882822C0000 2B0000AE8485B68E8EC69E9E613B3A350E0FA0797A9871722200007A5A4F5134269A7E70CAB0A3 9A8375AA9788847363C4B7A79A8E7E776B5B8C83729D9485665D4E645B4C5F534525190D1A0E02 31241B291C132719106A5C536D5F5635271E1F0E0661504886756D6A57506D5A5366534C2A1710 28150E3F2D236653444835243926181000001604002718110B00000C0100675D5B544F4B120E0B 0504000001000D0F0A0002000101001F18105F554C0800000E04000800007F766F393029070000 0801000400000F0A06110C0815110E4F4B48898582A6A297332910C6BB9F5348360D00000A0000 0800001E121210050133291FAAA094887F700E0400080000100406080005110511030002000000 000000000000020202030303030102010000030000030000030000030000040000040000040000 030000010000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000010000040000060000060000040000030000010000010000010000010000010000030000 0702000C04020900000800000600000002000C0E090B00001F00057F585DAB84896A4C4C230E09 0D00001C0902180000532A289F69697034369856585A1819300000AA6B66BB7E792700006F3E3A AB7F7C7C54522802001B00009068685C2E30865256561B1F99585C90494F8D464AAB6669561C1B 936C67210000B88888B57D80723439784A4A070000070000855551B477767D4842A76E67A45D59 7E3A373F100A4417113C0000A45858C66C6EAC494CDB7779A44646AC59559D544D601D14F2B2A8 88443BA257527A2926640106911925BD4350A93F49B55159D76D77B0424F9C2E3BD36D78A85358 5D0E13AD565EFFA3AFBD4E5F7E0F20AC4A577F28306E1E1FD387878B4545531313470F0E5D2B2A 3105045F39386846444627246548442508044E2F2C6543412D0A063B181463423D75544F916F6D 371611684644866560825F5D855F5CA97F804719192A0000622E30CF969CB77C8071323A6D2C32 AC676CC984895B191DB37578E9AEB0BC86862500005B2B2BD6AAABA47879A57B7C3B11125C3234 DEB4B662383AA27A789D7B72A38378B6988D63473B50382C554234BDAB9D8474654D3F3264584A 5A51424A41321F15091B11050C00000A000030231A483B3270635A9689805C4F466052493C2E25 887A7185776E58473F68574F4A39311906001000000F000038261C3A27193421122A170938261A 130200110200180B054B403C887E7C1A120F040000110D0A01000006070124251F030000574D43 9D8F840B00001305001F1209B1A79D261C130C0300170E070C0500070000070200040000030000 1814116C655BD0C5AFB2A68EB7AC9A0D00001A0C091A0C0B0A00000800000D0300C0B6AAA3998D 2B2117080000170B0D080005060005020003000000010101030303050505070707060405050304 030000030000030000030000040000040000040000030000010000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000010000060000060000060000040000 0400000300000300000300000300000400000600000B01000C00000A00000A00000A0000090000 0700001309071303031100005032349B7479A47D805434351F06021403000E00002D0E0B9A6C6E 732D35944B526F2D2E340000AA706E9E66652F00008A5A58B2828286585A230000400F139E6C6F 814A4F5A1F2387494C9A585C8B4649BC75796427268E635D360F08A77473D79B9D702D34825051 0800000C03007E4D49B67676824B46B37872C8817D8F49475F2A2483504C955553AD5F5F913739 903032D06E6FB4565494413B782E25CC887DC27E73530D03AF625C65120E7D161ACB4659D1485C BC4757EA7E8B952936C45867D06473D4737E843339A4575DEB959ED87383D25B71AA3047D8677B 801A288B3037E39195A45457A1565A70292D69282C4A0F1370393C5826278658585D3130663D3B 3F18136E47425E3730936C653E1511512824946B69562D29481F1D8B625E603433A27572B38182 9F6C6B420A0D4C1113A3656AF8B7BB813E456722279E595EC27D80874549D49699E2A6A8B27A7B 663234C18F90D1A1A18B5D5DA072743D0F11AE8082BC8E909A6C6E9F737298716CC4A2998A6960 715349745950B09A8F39251A1606004133285E52463D332723190D0800000800000800002F251C 41372EA59B92D9CFC6A399908A80774538307A6D6572655D33261E53443D1B0C050F000022110A 1C0B044837306A594F3523153F2E1E4735272210041A0900190A031306008D827E221816070000 0400000805000D0A050909010D0D05302C2186786B7B695B1806000E000050403376685D877970 1B0E05080000090000090200110C0617120E0500000400001B140A423723DED2BCFEF1E12B1D14 1708030F01000F01001A0D0710030031241B8B8177170D040700000B01020E030B070006020003 000100010101030303050505070707060405050304010000010000030000030000030000030000 030000030000010000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000100000400000600000400000400000400000300000400000400000D0707070101 0600000900000B00000C00000C00000F00000F00001100000800000800000B00000F0000311114 734F53AE8C8D664848311C19140100270B0A3B13148E525A7332388B51506D3633320000BF8987 753F3F3700039F686DAB74799E676D260000985F65884D538043486C2F34A466697F3D41B1696C 88464771413D5B302A925A5BE3A2A66E272F8851540D00001C0E01824F4CC17F808F5553BF8480 E096958F48462900002E0000995554B26464B95F61DF7F80BE5E5FAC514EC26D6695483ED28980 732D23C0766D63140D842F2CD36C70CE495ED3455FEB6C81992436B24354DB7080E07B89C26671 CF7C848F3E479F4551D06B7BFF9CB19B243ACD576DD8697CD4737EFDA3AC9F4850D68089A15059 883B438940499B555D8241478D51538850518A57544918146E413B63382F7B4E489F6F6B82504F 300000915F5E5927266C3A39D9A6A59A6766AC7475C18688793B3E78373B8D484DFBB4BA9B5259 6F262DA45D61C27D80834145C8878BFFC5C7C085876A3235BC8588B58183C39192AA787BAB797C EBB9BC4D1B1EBB898CA87A7CF0C7C596716B502D2774534CB2958D4C332C47332A645349615348 574A4150463C4B41372A2017352B22776D64C3B9B0DAD0C7C6BCB37B71682E241B1F150C6A6057 73665E1D100843362E0D000031221B392A231D0E0721120B1708011908005C4C3F665446110000 0E000024160D0E0000675A544336300800001A100E0700000400000601002E2B22030000686256 9C8C7D3F2A191300001A0700453325180800D0C0B335271C1104000800000700000C0500060000 0400001914100A03001509003D301FD6C8BBD7C9C02617121102000B00000A000024170F45382F 6A60561A110A0900000700000C020A040004000002000100000000000000020202030303030102 010000010000010000030000030000030000030000030000010000010000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000010000010000010000 0100000100000100000300000300000300000400000E06041F1514291F1E2115151005030B0000 130000120000200B0A1D0B090A00000A00000F00000E00004E3435B9969A976E7451272B1D0000 1C00003F181B936B6C613333824F4C6F3C3B592323D1999C682D3152151C85484FC6878F86474F 5D1E26A5666E975A5F672A2F985B60904F53964B4FB26C6C57242081524C844647DA939772272E 8F5456180600251307925A59C88485905654C98E8AE399988D43428245427E4140CB8585AB5B5C 943B3DC06262B25454CF7471B05B54F0A298853B308F453AB1625BA6534DDC8482E27D83C95063 EC6880950F2AB4364EF08194C25D6DCE7480E38B97CD717E7817287E1D2ED57485FF9DAFAA4054 F27E95FF8BA2D06B79E285906A0D18D77987CB6F7CB25766D98390E18D9AC5757EA35A61C58083 975A598F5551814F4652221640100678413E9A605FB77D7C652B2AAF7776642C2B5F2524CC9090 A16565BE8081DC9A9C995457591115CF8489E89BA166191F80393DCF8A8DB16F71CF8F90FFC4C5 96585955191BCC919391595CE0A8AB491215A56E719E6A6EA36F73CF9B9FC593969E70701D0000 704846D7B4B08F706B4E322EA38C868F7C752C1B1314070030261D574D44756A649D928CCAC1BA C9C0B980776E534A4140372E2B22197C736A5B52490E04002B21182A20172A20171F120A1C0F07 0A0000180B036B5E5696887F4F3F321808000D000027160C160800564740675A540F0200150A06 1209040700000C0500221B135753480A0600847A6EB19E8D220B001200002E19081E09000F0000 9684766A5A4D44362B2B1E150800000700000B02000B0400130C06070000110700140800786A5F FFF7EEAFA0990F0000190A050D0000130600776A62261C130F06010B01000700010400020E090F 000002000100000100000100000201000201000000000000010000010000010000010000030000 030000030000010000010000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000100000100000100000100000000000000000000010000050402 0300000500001F1A17413937554D4B5A504E5B4D4C3A21241E01051200000E00001709060D0600 0600000D02000F00003714188F5C65AC747F84515A2C0309140000472D2C855D5D7545437D4B4A 541E1E7F4448D09398531218844148843E48EAA4AC601D26AC6B71995B60713439793C41CD8C90 813539CD85864C17119A67637F3D3ECD828779293295595B261005230F04975D5CBE787A884C4B DA9F9BFBB1B0B66A6AB4706FC38280D48A89B66665A24A49B25857AF54519B423EB7625BDC8C83 95473DD78A828B3B34C7726FDE8483A7474BDC7080C14B63A82745E26380BB4E65EA8C9EFBA7B6 E58E9EE07D919C35488D2A3EE08493FFB2C1EE96A6FF95AB982B42CA6575E78795650513EB889A F592A4C66576EF91A1EB8F9EB35B69DA8791AA5D63A86262BA7A788D544B6A342A572117703332 854546A66667B9797A9050519456576525266C2C2DCE8C8EAF6D6FFFBBBFA65E6254070D7E2F35 FFB0B79C4D53884044BB7679D28D90F3B1B3FFC2C4A06061915356ECAEB1D99CA1A76A6F854A4E D49C9FC78E94B98086AC7379E8B4B83606063F1312DCB3B1926A6863403EAF928E6A514C432F28 705F5872635C796C6664595380756F8C817B776E67332A23373026463F35453C33675E55292017 0F0600291F16463C33463C332D231A271A120E01002A1D15998C84A0938B30231A0B00000D0000 2A190F6C5E551B0C056C5D56170A040A0000180D090800000B00001A1108685F566A6257070000 998D7FC6B1A01800001C05001700001B0400200B003A27189F8D7F5646397E70653B2E25080000 1107000900000700000F06000D03000A00005D5047807269F9EBE234261D1304001C0D06473A32 4136300C03000600001B161316121303000208080A010302000201000100000201010302010302 000000000000010000010000010000010000030000030000030000010000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000100010705000906 00040100030000020000010000050100010002020001000002010005010004000005010013100B 281E1C6A5154785B5F5D4344200C0B0A00000A0300110A0408000016010018000037040D824A55 AC798280575D381B1D1A00004B25248557576C3A3B864F526C31359F5E64CA848C4F080E934A53 9E555CD68F97934E5399585C9A5C5F703338B57377B7686BA95D5D8950498C5751A66263BC7074 96454C8747482A0F06120000955B5AB26C6EAB6F6EE8ADA9D8918F550909450000A25B59C37777 732322A6504FC66E6CC8706C923D38E18C8785322CC0706984332FB86561CE7877882E2EDF828A BC606FBC596EFC8CA5CD5B75DE768DF497AAD98595FFAEC0FFAEC4DB7187963549E08999FFC9D6 D48C98DE8A9AA44759E18594EF91A1B15061FF9EB2FD9AAEFFA1B5E58296E28192B45666BE6672 D38088D88C8E8C4646A96A63B97D75AD7169B26E6FA65F63732C30904B4ECC878A9E595C935153 753335BB7679D58E92E29A9EE79CA180333955060CE19097CE7F85792E32C88284EFA9ABCE888A FDB6BA8C474AB47274C28082CA898DA8676BD5979C8F5257874A4FB07579F2B7BB753E4159272A D9A8AB996B6D845A5BB48D8E4D2E2C3B1F1C927A767A67634D3E39261913352A246A615C3E3530 2C231E382F28221B11140D03150C03160D04251C13665D54887E755F554C20160D160C0344372F 4F423A8679717B6E66150800140700190B00312318AC9E952F211865564F382B230A0000110400 1003000C0000291C144F453B92887C494031080000A79A8AB7A28F3D2410462D191903001C0500 1100005643349987798D7B6D8B7B6E8D7F743E31280F02000D03000A00000A0000080000110600 463C331B0E057D6F66B3A59A1204000B00005548401B100A0800000D0805080403020200040404 0204030003020001000004030004031A1C1B2C2E2D0001000001000000000404040B090A0A0809 050304020001010000010000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000100000400000400000400000501000704030907000501000100 0303010000000100000100000100000100000100000D05021200002A1114665150988684726461 1C0E0B0B00001F0B0A1200002805091D0000240000774C53AB82868A63665D36394F2225330205 8C585A7E464985484D9D5C60C17A80944C506F2429873C41CE8388AC65699E595CB8777B6A2C2F 934E51BA6A6BB56765975C547B423BC27C7CBF70759C464F8B494B2E1109170000905454C07A7C 995F5DCE9490B06A68560A0A580E0DC77D7AB26462570804CA7975E18E8A98453FDB8882BD6A64 92413D8A36344F0000C06A6BB55C60F1969BD57B85B05D6DC77488DF8199FFAEC6C0627AA94D64 C66D83F296ABFFA4BBFFB5C9E78EA2D68594EDA9B4D3949DF5B1BCD48A97FFADBCC76F7DCB6E80 F093A5E8879AFFBACDF392A6E48396C466788B303FFFA9B2C8777D6E2425BF79777D3A348D4946 DD9598DB90958F444980383C9B5458B16A6EC98487AF6A6D8B4448BA7377D28A8EECA1A6CC7F85 490000B26168E99AA084383CC1767AE1969ADA8F93E9A1A57D3539D18A8ED89195B77277803E42 A5646A985A5FD19398DA9DA2773C403D0508C99297B684879B6A6DA27677522A2B72504FB99B99 7159552D1A166E5F5A60534D382D27766D688D847F342B26160D060D0400070000130A01665E53 9E958C8880754C42391E140A31271E786E646C5F5765584F40332B140700160901382B2243352C C1B5A9594B4241342B6B5E560D00000A00001104000A0000120500473A3172665A998D7F271B0B 120500978777BEA9964E38236349381A0300190200120000433021927F705F4D3FCDBBADAF9F92 7062574D3F34120500170A010A00001207050D0301514841251B12261A0ECEC2B4514336100400 4C42390E0500120D0A0908060A0A08030804000200010705000302000100050908000302272928 282A29010302030504060606060606040203010000010000010000010000030102000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000100000A06 000C07000905000400000300000200000200000100030301010000010000040300060501040300 0100000400000E00000D00000F0402453A388879769E898878585B452125210000150000190401 0E00001400006B4344BB7F8785464F723B40572528280000864B4F793B3E9B595B793335CE8689 803539853A3E7B3034F0A8AB995355A86366A05E6071292CAB5757BE6F6BB97D75723731CF8788 B36268A24B54924D504024191B0000985C5CCD8789B97F7DC9928DA4605D631918722724D68884 5E100C91433FD98C86D1847EC57671D2837E9F504BCE7D7A6E1A1AB55F628A3339CD737CF195A0 FCA4B2ED9CAFE297ABD58EA0FAB1C4EA96ADB0546DDC7C97EE90A8FFB0C4FFC7D7FFB5C6D9919F FFC1CFE0A1ACE0ADB4E7B2B8FFCCD7B46471DF8B9BC26E7ED77E90FFC6D8EC90A5E68B9DCD7486 C66F7FF09AA5B16067AC5D62CF83856A201F8C4243B96E73D88D94D2878EE0979E924B51712A30 934E53C58085AD686D884147C98288D99097FFB8BF94474F50030BFFB1B7D3878BBA6E72E4989C E19599D4888C984C50D5888EC87D828D4549995256904B50BD7B7FD6989BB4787A864B4FBC8185 BB8386C48D90A270715D2F2FBC9293B3908E6546446D545079645F6E5D567467619489834A413A 181109140D052920192B23185C5246B8AEA4DFD5C9AFA59B3F352912050064584C7F726943372B 91837A84766B392B2244362B3D2F261D0F06AC9F96C3B9AF31241C453830291C160A0000170A04 1003000D00000D000073655A7B6D609487770B0000150600897A679B8675533E2B988171180300 331E0D1C0900443122907D6E221002D6C4B6CEBCAE8575686454477A6C610B00001A0D051C1213 1D1415453D3A221910080000BEB5A4A094841B11053C332A060000161211090909191D1C101914 00090318231D000200030706070B0A0003023B3F3E2226250406050F11100A0C0B050706000000 000000000000000000040203060405000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000100000400000500000400000300000200000201080806 0D0C0A0300000400000400000400000500000501000502000601000E06030900000700000B0000 1100002305076F484DB68F92B39394523935100000150200170000200000662028C67F8791565C 885456541C1F290000A06263A36162A96363752E2CCC8281621817954B4A954B4CEDA5A6732B2E BC76788D41438C3635BC6B67DD9E95884D45B56B6AA04E52A9525A924B4F46281E1400009C6060 BE797CE2ABA8C28D879453515309088C3E3AAD5E595D0F0BBD726CDB928B8E453EE79C96893E39 9E504C701E20C16C71D27B84D57B87D27786913446B45B6FF8A6BCF8B0C6F2B5C7C28595EA9FB6 CF7992CC6F8AFFB1C9FDB6C8F3B5C2E9ABB8CC8A98FFD2E2E9AAB5BF9297DFB2B7FFCED6D48C97 E59BA8A05461DE90A0FFBACAE594A5F1A0B1E693A5CB7888E5939FED9CA5D28188E7969CDC8B91 C8797EC679819F545BA1555FFFB6BDCF8890A560658B454DA66468D39097AF6D718A444CAA6369 EFA6AFE0979E782C36BD7078ED9EA38A393FE7969CD8878DB8676DCE7D83D18087C07177782B31 A0555AC57E84F5B3B78544484C101294595DE6ABAFE1A6AA9F676A8F585BD1A1A16F43446F4948 A684827E625F75605BA3928B72655F3D342D3128215851495D564E332C229D9387FFFEEFBAB0A4 3D34250B0100362A1C8F8377786C5E35291D97897C84766B0B00005B4A406555482C1B11897B70 CABDB44D43392B21182D231A0A000014070120130D0A00001809021F11089183787D6D5E7F6F5F 0D00001908009A89755643324E3B2CBEAB9C1100005946372110005643357C6A5C0E0000897769 B6A4969D8B7D3E2C1ECCBAAC453325190B020600001A15190F0A07060000070000756E5BC3BCA9 0F0800332C220D0A050B0B09050908242D2A101C1810201627372D000300080C0B020605000201 4E52511B1F1E030504121413060807000100000000000000040404040404030102020001000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000100 00030000040000040201050402020201000004000006000013090A14080A1206060D0101090000 0800000A0000070400000300010300362626725358734C513F181D1B00001E09044B3A33A39089 AC8F897047456C3636793D3F5D1B1D3A00009E6367955D6094595D3C00022B0000864543BF7B78 AA65609E5753CC827F611714873C39D68A8AAE6264873B3DC07071812B2AAB5A56E3A49BB2766E 914545A24D52B75D66874143492B21180000AD7372CD888BF5C0BCBE8C85783B384D0604B86965 AE5E57AE615BDB928BBD776FB7736A954E48924943AE6262BB6B6EC7717AF098A6F499ABBB5F74 E2869DDC829BE48EA9F1A5BFE9ABC0CD92A4DC96AEFFB4CBBD6D86FBB2C6E7AEBDF6C7D1F1BDC9 AA707EF1ACBEF5B5C3CD9BA4E4B5BBFFC7CEF9BCC3EAABB4B1727BE3A1ADE8A6B4FFC1D0FDB6C6 E299AA954858E597A5EA9AA7AC5865D7818CB8626DC5727CF2A2ADC0747EB66D78E29BA3BD7781 CA878EC38089D19096D998A0D3929896535C702D34AA646EFFCFD7D58D987F343BCB7A80762126 DD888DD681869D484FD07B82C37177A6545A86373DAA5D63F0A7AEA15C613500009F6365EFB4B6 D29799894D4FC28789BA8283956261DFB1B1825A5851302BAF938FC6B2AB7B6A6294877F7C736A 534A41211A10302C21B5AFA3CFC6B73C30202014060F0300685C4EC0B3A36052454A3D2D615346 89796A0D0000726253705E520E00006A584CF6E6D963594F170E05120701170C061308020B0000 1205000C00001203006D5C52918174AB998B5B4A3810000035230FBAA995201001544437A19184 0D00005B4B3E4333245D4B3F4E3C2E1100003826188A7768BAA798463324766354CEBBAC1A0901 0400020D0A1103000003000018150265604ADAD5BF161100302C212F2E29000201070D0D25312F 00110B192D2224362A0004000E14120002000208065458570E12110001000B0F0E090B0A000100 000000000000020202000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000100040807020605040605050505040001060000 0A00001304070B00000D00000D00000D00000D00000B00000E00000B01000406010A0B06110101 1800013A1A1D664848755D5B6A5751412E273F241D6E4541AF7977B878799755568A4A4A915453 6E333583484CBC8082AD6F707E41405C1D18A4635DC8857D77322BAE6761A85F597C312C964846 FFB0B16B1B1CC3717398403E96463FC98B80D89C92843936B25D60BD636C813B3D482A20361B10 BE8483F4B2B4EBB8B4BB8A8560252176302ED1827D9A4A43CA7D75C37A71AF6B62D9968D76332B 99544F6D2123BB6A71D98390F79EB0C4687FFFA7C0E588A3F89DBCD07797C97694DE98B2F4B5CA FBBAD0FFC3D8E8AABFDAA4B4E7BBC8FED4DEFACCD7B88490E6A8B7FFC9D9E6ACB8ECB4BDFBC4CA FCC8CCEEB9BFDDA8B0D79FAAD69EA9FFECF8F9BDC9FBBBCBB36F7EE298A7EFA1AFCA7686F29AAA 9F4453BA6270E393A0DB929DFFB9C4E8A2ACAE6B74B8777FD4939BF5B6BEECADB5D09199E6A7AF 92535BAB6A72F8B7BFE9A6AF984F58BB696F953C42B75E64DC8389AB515ACB747CCA737B832E35 76252CF1A4AAA960674E090EB67579E6AAACA56A6C915658B87C7ED79B9DB07577C48E8E815151 976E6CE7C4C0CEB1AB9079736B5A521407000700000F0600433C32C0BCB17E786C080000281C0C 0A0000776A5A9689795F52428D80705242336151421D0D00A896886957490E0000534133FDEBDD 87776A1A10060A01000C01000C01001106000D02001104002A1B140D0000B4A399827064D7C6B6 311E0D110000614F39BAA9950B00005C4F465649400B0000392B209181745F4F422B1B0E190700 170500857263948172A08D7E100000C5B09F4F3E3408010809081012121016160C04030087856E DED9C33936232220144D4E49060A0B1822232C3B38061913233B2D293F320009031D2321000200 131917525655030706000100131716181A19090B0A000000000000000000000000000000030303 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000001000004000007000014050A2A171B3C272C654E54664D535D44484C3337 3B22262913161701030E00001200010F01010C04020803000400000600001402002A110C67413E 9568657B43425C201F965956C1827D9D5E5977373586484BA6696E9E6063AC6F6EC386839F605B A86960B1716799564D8B473EB36A63A25752944541C87776CB7679964041B45C5A86362FAA6C61 F0B4AA8E4340B45F62B45A638F494B55372D44291EC38987FEBCBDDDAAA6A06F6A4A0F0B9D5755 AB5C575F0F06CA7D75864036CD8A818E4E4498584F7B3734AA5F63BD6D76DA83939E4559EF93AC F699B6FFB2D1E58AABC4698CC86E91FBA1C4F8A9C6F1B1C9D0A0B0F0CCD8E1C2CAF3CDD8F5CBD5 F3C8D2E0B0BCEBB9C4FFD3E1F2A9BCF0A9B9F7C0C6F9CBCDF6C9CCEFC2C7D0A3AADEAFB7FFDFEA F3BFCBE3A9B8A96B7ABB7486FFBED0CD788BFFA9BBED8EA2BF6475E799A7B46C78DB939FC7818C E8A4AFF6B4BEECADB6DA9DA5E6A9B1EDB0B8F7BAC2F4B7BFECADB69E5F68D5939DBE777FB05B62 9F444B8E333AD57A81C1666FD97E87CE747D89323ADA878FAC5D63671F23B67174D89A9DBA7F81 D39B9CC088899D5F608C4E4F975B5B8F5957CE9E9CCDA4A075524C1900001100000E00000F0200 0E060071695EA09A8E2C281C0A04001509001D10007669587262528B7B6B9C8C7C3C2C1C4F3E2E 453424AC9B8B4A3728140100392617E5D2C3B7A4950D0000150B01070000150C05070000100500 211610372A2433241D37261FAE9D93938175BCAB9B1A08001301008B775F9685710A0000685E55 3B31280F020022150CD9CBC06052471E0E011F0D000F0000816E5F725F50E6D1C03C2716533C2C 84736903000421212B0E0E0E0C0C0203020079795FB6B49D65624F0909005A5C57232929364242 3646431C312A213C2D334B3D0A1710303634080E0C2E34325155540408070E1211373B3A171918 090B0A000201020403030303000000000000060606000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000000000000000000000000000050505030303040203070304070001 0800000F00041D080D1C050B2A11173D222751363B664B5074595E6F555866494D3B1B201F0206 0B00000600000A07000C05001100001A0000200000230000663030A36D6D844E4C703B379D6663 C68C8A83454869282C9B595BBE7C7D92514FA3625E69261EBB776EE49E968A413A934640C47570 B05C5A9A4443F39A9C973D3DC36A667D2D269D594EFDBDB39A4F4CA55556A34E53A45E608D665F 603E35DA9E9EFFBFBFF0BAB88F5C58490D0CB4706D7429237B2E26CD877DB9766DBE82778C5046 7B3F379A5955DE9397F6A5AECF7787E78A9FE1839DFFA2C0D77898E78CADFFA9CBFFABCCEB91B5 DA89A9D89CB5F8CDDEE1C3CFEED3DCECC6D1F8CEDAFACFD9EABFC9D0A5AEFBC7D3F4ADBFECA8B7 F3BEC6FFD9DCFFD5DAECBFC6DFB1BBF7C9D3E5B5C1F9C7D3B78390D79EADCA8A9AFFB8C8D48598 FFADC0DC8395F198AAFEADBED28595F6A9B9A75D6CD68E9CF1ADBAFFC5D3F8BAC5CD919DDBA2AB FFD0D9FFD0DAF3B5C0A4626C934F5AD68A94B55E64A5494C983C3FCD7176AF5358C1666D994046 853035CB7A80B76B6FB87073C681849E5E5FAF7375A4696B804645BF8182BA7C7DB77D7C945E5C 6737354017131800003419122E170F34211A51443CB6ADA4ABA49A64605539352A2E2A1F5C5447 887F70817567AB9F91B2A5955144343B2B1C685848AF9F8F776656281707483628FCEADCB6A496 0F00001C0E010A00001910070A0100070000493F362C1F1762534E1B0C0577665E806F65BBA99D 7F6E5E1A08001E0C00A3917974634F1F13057A7066584E441E110821140BF6E9E05D4F46150700 2D1C120D00005D4B3F958375E1CFC19887772815068072670500035E5D630B0A080202000D0E00 5658439E9D899697870002005F645E3D4645485754374744263B320D28192B43351121173B463E 121C14424B465359550C120E282D295C605F020403000100000100030303040404000000000000 000000000000000000000000000000000000000000000000000000000002000002000002000002 000000000000000000000000000000000100000000000000000000000000000000000000000000 000000000000000000000000000000000000010000010000010000010000010000010000010000 010000020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 0200010101010307080002020002020000020404060703040800020900010D00001000010F0000 1100001200002F121765464C916E74B88B92A174797B54574A28291B00001500001500001A0000 1E00001C00001900002400026C484A9672728864647A4C4ED49699A86165783034853D40BA7273 C97F7EA45858813331D38382EA9996AF5958923A39D57A799A3C3CAB4B4CEF918F963D37B8665B 8E4137E1978EC87D78B86E6BCA8081AD6B6C945C5B511E1BB97D7DD69899D89C9E5D2121490B0C A664655B1812C6837AC5897ECD9489955F53D39D91C48981FAB9B5F3A9AABC6971D67A89FFAABE FFA3BBE07C98CB6684DA7D9CFFB6D5FCB5D3FAB3D3EEACC8E1A7C0E8B7CCF1C6D7ECC3D1FFD8E4 FFE2EFFBD1DBDCB2BCCDA4ACFFE6F0E9B6BFE4B1BAF9C7D0FACBD3F4C0CCEFB9C6FFD7E5E8B2C0 BA8494FFD2E2DBA8B7EEBCC8B47E8BE7ADB9D999A7F9B2C0ECA0ADEC9BAAF39EB3C97187EC94AC AA556CE995ADEEA0B6EAA2B8EBABBCD499ABD9A0AFFFC7D4FFC7D5FFD3E1FFCCDAB66878782431 C86E70CD6F6D8E302EB95E5DC26867C66E6D772323A85756AA5C5CDE9493A55F5F8642439E5E5E 965859A76B6BCB8F8FB97D7D753938763E3D6A3734835653916A65876661876B6778605C998783 AD9F9C7168633C34312D28242A25214845406B68637D7A73ACA89F8F887E1C14091F1509433729 9285753D30200D0000372718F0E2D5C4B6A94A3E303024180C02000F0700110B00070000362E23 6A605653463D63544D0B000074635B514036BCAA9E3C2B1B0E000044341D83735C796854483B2A 796D5F594D3F2A1E10180C00CCBFB69B8E85180B031104000A0000594C438B7F739D9185B8AC9E 1D110353493F100805716C69413C380300000101005B5D52A0A398AEB4A8000300525C541B2821 505F5861726A24382D1B2F2425392D102514344636223323556356232F25131D15767D76323733 0204010000000606040201000302000D0C08181713000100080806000100050601010200010000 0100000C0B09010002110E1501000708050E030007000002020200000100000100000100050908 0001000001000D0E10000002000103010204000002000002000002000002000002000002000002 010000010000010000010000010000010000010000010000020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001010101000202000302000202000405 0102040000000300000600000700000C000012020514000210000015000022070C32121750262A 825558A57B7FB78E92BC95988E6C6D4424251900001700001A0001290C10150000120000341A1D 7D60658E656B83454AC37B7FB1696C7E3639924849B86E6FBE7070BB6B6C5E0D0C954141FAA2A1 C16767983D3CC163638A2B29D67974A14A41AC5A4FA5554CA1544CE9A09A9E5954A05C59854543 7A3C3D3F0102A76B6DC48689D6989B7B3B3CB17172B87677934F4CC7877EC0847AB37A6F986457 B98377E7ACA4EDACA6CA7E80DD888FFFA6B3E18091B04D62D06C84F894AEF59BB5B16684E4A3C1 FFC8E5ECB0CAD99FB8F2BCD3FFCCDFE5B5C5D0A2AFEABFC9FFD5DFFBD0D9E3B8C1FFE6EDDFB2B9 D1A4ABF4C7CEF8C9D3E1ABB8FFD0DFFFD2E1B97E90B67D8EF2BCCCEEBBCAE7B7C3AD7D89E1ADB9 EDB3BFFFCBD6FEB8C3FEB0BEF79FB5DD819AF598B3BD637DC6708BE794B0CA8099A36278C2879B E0AABAFFE2F2F5BBCAE8A3B5F2A8B9B86577A94E5DAD5152C669628C2F2A9E433EE58C88D17C79 812D2BAB5C58E193916A201F7C36369955549C5A5BE4A4A4DF9FA07B3D3E7134339B5F5EA8706F BB8885D9ACA9B9918FB08E8C8B6F6BAD95937E6C684F4140160C0A060000050000201A1A5D5958 7E7E7C78797463625D514E47241D15140C01756B5F34281A0B00002B1E0EF0E2D5C1B5A92B2115 090100110900140C01070000160F000C0500958B7F4A3E329A8D842B1D1437292065544A4F3F32 806E621201001504005544306F5E4A5647328D806D180B0084776736281B0A0000BCAFA6BBAEA6 0F02000C0100180D07433930776D644A4237CEC6BB362E21150F031D160E1D181238332F2D2A25 1B1A15292C2581867FA8AFA7030D05343F373040365263596C7D733A4E432B3F3422382B29422F 253E293C513E5062522333263E4A406F766F0E130D0001000E0E0C0100000100000100003A3934 12110C0807020304001415101E1D180707000F0C030300000300000300000300041B151F0F0915 110E17010002060702040500000100020401000100030706000100000002000002030406000002 000002000002000002000002000002000002000002010000010000010000010000010000010000 010000010000020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 0200010200010101010001000103020507060608070202020100000A06051610100F06070E0604 0D03020B00000C00000E00001303031804051200002103034A2D2F543A3B503838786060998483 8C76785E484A2F161A110000140000260B1024070C2A0B134A2127773C40B26D70AD696AB06C6D CB8585975151803635CC8080CB7D7B5505045D0C09FFB8B6C97471A44C4AAC54508E3730D17F74 9F4F44994C4280362DDE979184413BB3726E814441A264653A000097595ACB8D8ED69697551314 A36162581212B66C6BAC615EB7726B68281F9E6258D0968BDE9F98C3807ADB8F91FFB8BEE18791 A24655D37689FA9DB2E78BA2FDA9C1FFC9E7CA85A2B97793EDAFC8FFC8E1E8AEC4CE97ACCB96A8 CA97A6D3A3AFF0C0CCFCCED8E8BAC4FFE7EEF4C5CDE6B7BDF0C3C8D9ACB3C9969FF8C2CFF9BFCE C08695CB92A3E7B1C1FCC7D7E6B4C0B88692D49EABEBAFBBFDBBC7F0A8B4EEA0B0E38EA3FFB4CD E68CA6F199B2F4A0BAEF9FB8D0869F9D5C729B6074FFDCEDE5ACBDE6A9B9EFA8BAB46779DA8598 EF94A3872B2CA84B46C36563BD625FC56B6A97423F9A4644B96A666B1D1B792D2D964E4F985252 AE686AB87475A15C5FB77577D08E90BC7E7FA76D6C834D4B7745444C201F583533896C68260E0C 1502000A00000700001E16144B46435C56566E6A691C1B1716151116130E0D0802433C346C6459 1D13070A0000423628BCB0A2DDD1C54B4135130900140B020E07000600001B1203080000776E5D 74685A867A6E8A7C711605007160563D2C228E7E71412F230E00001B0C007A6B56291A05867762 9D907D302312857969463A2C2A1E129D9087D6CCC30C02000800001D120C4138316F665D070000 A59D924B45370400000E0B041918130A09055756522E2F2A0001006C6E6980857F1D271F131E16 34433C2A3B334D62593D544A203A2F1531224E6B573F5C464059465168580B1D11626F65636D65 000200080A070000000D0C08030000322F2A726F681310090603000100002C2B27423F38242118 2D291D0A06000400000F0A040400001F191D463F460803090100000F0E0A000100050600020401 000100090B0A0002010001000F1110010302000100000002000002000002000002000002000002 000002020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001030200050304 05040203020008040316121126221F56524F5C5754645F5C68635F66615D5B56524D4844463D38 392A271C0A080B00001405023B2C29241512150505412F2F705C5E937D807D64683E2328170000 1600001A0002562D352700003C0000935353D29091B87775A56160A55F5D8A4341CA807DB06562 6E201C651713FFB8B3C9787483332C8B3B34BA6A61AA5D53883E35A25C54E49F9A9B5A56AA6D6A 7D423E7E4241370000A36665CD8D8DAB6A68430000CF8B88BE7473CE7D7CCE7D7C90423E813A34 D7948CD99990F0ADA7CD8883E09494A9595CA8525BC9717DE18999E891A2DD8A9CE091A6D98FAA FFC0DCFFD6F2EDACC4BB7D94C68B9FEBB2C5F5BFCFDCA8B5C3919CCB99A4DBACB4D5A6AEFFD7DD FFD0D6F0C1C7F3C9CDC99FA3E0B1B7EBB8C1F0B8C5FDC4D3E1A8B9CC96A6F8C3D3EDBAC9DBA7B4 D49CA9E8AAB9F8B4C3ECA2B1E799A9B25F73EA95ACAC576ED48098FFB4CEE698B0B16981D897AD FFE8FDFEC3D5D79DACE8A9BAE299ACC5768BCD758BBE6372FA9EA1E18683F69B98F9A09CEA9290 A04B488B373561100F863637A95B5B924849AA6263D0888BB36D6FA65F63A96266A35E61904E50 7032336025273D090B4D1F1FAC86856A4B494C32313D29282C1C1C382D2B6E6463837B79504A4A 1913130B0704030000110C0607000052494040362C5D53496B5F53A79B8FF5EBDF4F4539070000 191007080100040000160F051004003A2D1C8F82716F6252BDAFA24F3E342E1D137A695F443329 907F752210040F00001E0E008374610D0000C1B4A15649382D2111A397894B3F3316090091877D 948A81170D041106000800003930295E554E070000645C51534D410B0700000100343631151611 2B2C27242520000100454641535550434A4319241C3C4B440A1E153E554B57736719392C274738 56776261826D2C4B395A756402180B7A8B8148534B0003003537340F100B0300000A0702504D46 534F46534F46312C260400001E1916524B43474135453E2C120B00191200292114332A232B211F 6960610400000703020201000D0C071A1B150000000001000101010608070001000C0E0D000100 000100000002000002000002000002000002000002000002020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 0200010200010200010400010500000600000400000400000400000501000D090616130E0D0A05 07060103020005050011110925261E3D3E364E4E446B645C7E756E8B827B6057502A211C302521 2A1F1B0B00001B09090F000042282B997A7F9D7A816C474F451D262D00076A32354204052B0000 5D1D1DAB6B69C38280AD6C68A25E5B75302BC7807CBD746E651C166A1F19FAAFA9A55B528E4139 7F322ABB706A90474086413AC98680C58681773C38894F4B8349456E332FC98C89CB8C8797544E 6B2621C57E78C67874DC8385A74D4F8F3938CE7F7BC47B75EAA39DA9625ED68C89BE7070A65659 C67079EF99A4F5A1B0DF8E9DD38696EEA3B7FFBFD5DE98B0D08AA2E5A1B6F7B8CBF8BBCBE3AAB9 CA94A1F0BCC8D3A1AAD7A5AEEAB9BFE4B3B9FFD0D5FFCFD4EFC1C4E0B8B9D7AFB0FFD4D9F7C5CE E4AEBBF4BECBD09AA8A26C7ADBA6B6E3B0BFEAB6C3CB919FE5A5B5FFC1D2F4A5B8DE8D9EF1A0B3 E798ABD17F95D48298FFB0C6EDA2B7B66E84FFC9DDFBBED0E2A7B9E4A7B7FDBDCEFFC7DBF2A0B6 C56C82C6697BC4696EE98F8EFFA5A4FFB5B3FEA6A5BB6564C97575F4A3A2DD8D8ED98A8DD5868B ECA0A4DD9096C77C81DB9095C77F83BC7478C78084D39195A4686ADFA8ABDAAAAA7850507D5B5A 543A396854537A6A6A7F7472615756251C1D090303120D0A312C2868615B3831292F261F0A0100 180E04342A20C5BBB1D9CFC5796F651E150C0E07000600000601000300001D160E0B000091806E 6A5B48B8A898B9A99A2212056C5C4F4E3E31806F652F1E141505000D00002D1D0E695C4B372A19 BCAF9E1609000B0000AEA2947C72660C0200796F66968B851B120B1C130E070000160D06322B23 1912086761555F594D0705000B10090F15114D524E0002000303010A0A080F0F0D4F4F4D545955 333C3742514A000F063A54497191841337294067555A816C587E673659454665532A4234899D92 1B281F000500262B2542433E0300003B3630605C53241D139B948A453C3512080710050362554D 75695961553F1F13003D3117473B23453A285E5246493E380800000D0805030000605C591C1B17 010000141510010000060604020200000000000000050503000000000000000000000000000002 000002000002030102030102030102030102030102030102030102030102020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001040000090100080000 0800000C04020D0503050000040000040000030000030000070400060600040400010100000200 0301001006001E110931221B6657509C8D868D7E79705E5A7C67642A1210200305160000190000 39101874465096677197646B71363A8549496D302F3400003300007F3E3CBB7A76C37F7CC7827D 7E3733C27B75B46D67671E17712821F5ACA3AA6158772E278E453EB06B64601D177B3C37D69994 8248448F55517137335116109A5D58CA8983C7827BB8726AB66D64B0615CBE64648C3033BF6766 C87774EDA29D9D544EC37976671C194400008E3C40D8838AD17B84C2707CE294A1FFB8C5FFD4E5 EAA2B6F1ACC1FFBCD1FDBDCEEDAEBFE9AFBDEEB6C3E6B3BCFFCED7F6C5CBFACBD1FFD2D5F2C1C5 F7C6CAFCCBCFF4C6C8D4AEADF6D0CFFFD7D9FFD6DCE5B2BBD09AA7E2ACBAC7919FE5B0C0F1BCCC FFCAD8D497A7F0ABBDFFD7EBF2A1B4C9768ADB8E9ED48797CF8294FFB4C8FFBCD0FFB5CAFFE7FC FFD5E9E8ABBDD699ABEEAFC0FFC3D5D58A9EDA869DFFB0C7E18496FFB7BBFFBFBCFFBDBCFFDCDB FFC2C1DA8686CB7777BE6C6EC8767AB26265BD6C72B96A6FC8797FD78A90C87B81DC8F95CF8489 AC6468C98489E4A6A9D0989B8D5C5F845A5C805E5D7053557A65647765657A6E6E726869514849 433D3D403B383D36303E352E5249425F564D2A201731271DA2988E9D938AA49A910E05000E0700 0E090309040015110E15141004000040302183715D8B7965C7B6A47564543A281A7C6C5F463629 7F6E640B00000E00000D00004A3C2F605343483B2BBAAD9D1E12020D04008F857980766C534940 898079A49B941C130E080000160F09080100140D050A03008881776C655B050500131D150B1811 353E3B393F3B0001000A0A080504025857556668655258544F5C550007002541355F8375103929 4E796684AE98456D55577D680C2D1A4C67586D8377010E050008000A0F094B4C4619160F746D65 4740367B736871695E4339302C1E1D0C000067564C897A65736447281A004E401D53442355452B 796A553022150B01000700003D3835615C590C08051F1B182B2A25030000020100020100000000 0807050D0D0B000000000000000000000000000002000002000002030102030102030102030102 030102030102030102030102020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 0200010200010200010200010400000B03010A00000C02001107051107050C04010901000A0300 1007020C03000700000700000700000700000D04001608001400001600001B00002A0C04250700 31120D4F2E295C3935AE8885B8909095696A67393B511E233100023000005E252BAE7274CE9091 C58585AA6A6A9554526824235C16148D4644BB7470C07673BE756FAC635DB269626C231C712B21 E59F959E585067201AC07B768746405B1E19BD827CA76E67723B34652C25460B0392534ADF9C93 DC968CC97F74CD8174E3938AB25A59C86E70E48E8FEB9B9ABC716CC47B758F443F7B2D2BAE5C5E E18C91C36C74A34C55F19DAAFFC4D1DA8C9ACD8593E8A3B5DB9BACDC9DAEE5A8B7EEB4C2FFCBD5 FFDEE7FFE0E6FCCDD3FDD0D5F9CCD1F4C7CAEBBEC1E6BABBEEC0C2ECC2C3EDC7C6FFE3E1F9D1D1 FFD2D5FFCCD5EEB9C3FAC2CFECB6C3BD8795CC96A4E7ADBCBC7D8ECC8597FFB3C8C16C819F4A5F BC6F7FB66E7CB46A79FBB1C2D58A9ECC8397FFC4DAA56176B97A8DB6798BF7B8C9F5B2C4FFB7CB FFC3DAD0778DC06375AD565CBA6664E38F8FFFC8C8FFB6B6DE8C8ED482848D3B3F95434775242A 94434995444A8B3A41A8595FAF6066B3646AB0636BB66B72E59EA4BB7A7E9A5F638D5B5E825558 7854548466688C77766553534234343127282E2526433D3F473F3D1D140F080000130900140A01 352B22A0968D887F76A198913027200D06000400000300000D09060100000B0A08040000756454 634D38B09B88AB98872817077C6A5C4030236A594F3729201D10070E00001105006E6256574B3D 443629AEA093413527170E00A1978B2F271C5E554CB5ACA53A312C19110E06000018100D110906 17120C040000827E736C685D20221707140D3647410A1614656B692C2D2F060405171314343031 54545451555467746D0011081E3C304266581C473646735F87B39A456D535D836C001200546F5E 304639263329121C1326292222221A9D9990241D13888075695F535F5549594C43362420160300 624F407E6D5382704C3825005644165E4B2078664278674B2312000B0000190E087A706E352D2B 0E09063B363228251E201B170A0702030000151410312D2A0E0D09010000010000010000010000 010002010002010002030102030102030102030102030102030102030102030102020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001040000050000 0600000600000800000C02000F0503190E0A2318140D00000C00000F0000120000150200160100 1200001500002D00002F00002700002700002800002C00002F000037040146100E4F1917703837 945C5DB87D7FD99D9FC4868B85474A4E0E0F6020219C5C5CB270718E4A498C4445994F4E7D3332 7F3431A35855BE736ECE837EAB605AA75C5670271E7C332AEAA19B944D479F5A55975650541712 834A43AD746D7B453B662D245D2318AB6D62F2AEA3F1A99DDD9184D8897CB361569D4746E38F8F E0908FB06562A75E584E07015C130DC77975D07F7EBA6467FBA2A8FFABB4B8606CB4606DD88694 D18794D18F9D9C606C8C5260AE7681CB96A0DAA8B1E9BAC0F3C9CDFED5D9FFDADEF8D0D1F5CDCE FFD7D7F8D0D0F5CDCDEDC5C5F4D1CDEDCAC6E7BFBFDAACAFFFD0D7FFDAE5CA929FAF7784A76E7D C08796EDB0C0D18E9FD68B9FFFBFD3D77E94CE778AC77B888E4652CD8390E89EADCC8293FFC1D4 EEA6BACD899EF8B9CCFFCEE0FFCADBFFBDCFD78EA1A7556B9D445A8D3446923D44D58483E49294 D9898AE08E90C67478F8A6AAFFAFB3CF7D83D17F859F4E54A5545AC37279B9686FAE5D6497484E AB5E66C98087BA757AAF6E74B67D838B595C764C4E3E1A1C4A2D2F3E282A1F0C0E2C1E1E372D2E 2D27274842445D5553685F5A61574E180E0508000060564D675E577A716A6A635D1D1610221D19 0300000A0603040301010000020202403933705D4E5F4934C0A9977A6756433222746455241309 6C5E550A0000080000180B030A0000877A713A2E225F514675695B43392D585043B7AFA41E150C 362D26918A840700000A02000E06030400000E0905231E1A0601006C696068655C373A31000C05 3F524E24302E2932317E7F810A080B1410110300000705061B1D1A69746E0E1F1725413526483A 1841311D483451795F486F544A6C540929125C7562051A096470642C3429000100524F46BDB6AC 696156998F835047383A2E207163564E3B353E271F7A65508C7758AC976C66501F7C6531897240 927B5186724F1100000F00005B4D447F7470392F2E251D1B463F391612093C352D15100A040000 3A3732524F4A0B0704030000010000010000010000010002010002010002020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 0200010200010200010200010200010201000504000300000300000904000901000800000C0000 1A080626110E2309081E02011A00001A00001900001B0000230000510708671110721E1E772623 80302F8B403D9248458F4846934D4B7C3835621E1B4E0D0B480403591514854142B06C6DCA888A AF6D6F9551528B45478E4647984C4EA65858B36364A9585794434291403DA75653C1726DA95A55 A1544C5E1109863B36E39A94B16C677C3B357A3E365A2118B279709660566D342B4A1005AB6B5F F5B1A4C57B6EB06154A14E407D291FB2635FEAA09FAD66627D38334F0C045A170FB7706AA1534F B76363DA8185CC6F77A2424D9E414CB65C68C9717FD28491D798A3B88089D29DA7EFBEC4DAABB1 D8AEB2F4CBCFF8D1D4F7D3D3F5D3D2F6D4D3FFE5E4F1CFCDFFE4E2FFE3E1FDDAD8F3D0CCFED8D5 F0C6C7FFD3D7EAB5BDE7ADB9FFD5E3DAA0AECC92A0A46776D090A0D08C9BB06375F9A4B79A3D52 D67B8DBA6E7ABC747FFCB2BFFAADBDFFBBCDDF94A8E299ADEBA6B9EDAEC1E1A4B6D89BABCA8A9B B0697BA4576BCC778CFFAABBFFC2CAC37374D18184914245B36366E2919797464C934248C37279 D6858CDE8D94D7868DB26168AD5C63C4737AD8898FC97E859B545A67242B42050A652E337E4D50 9E7677AC8A8B7E64652E1A1B2313140F03030A01020400000802040400000E03002D20185A4F49 8C817B8D847D4A433D645D57060100130E0A3E3A37120E0B0100000504020100001D1B1C6C6461 412E209A8371AB94844431228876681202006F62590F05000800000900000E030013090091847C 1609007D6F66564A3E0B03004A4438B4AEA2090200544D45504943150D0A050000040000080401 0A0603423F3A1A17124D4D4552524A696E6706151021343073827F0003026E7273575759040001 16101204000010100E61676318281E243A2E0011021638280E341F385C424A6D4F506E54082209 455B465D6E5C51594C373B2D46463A666256544C41D1C7BB2118097E72623D3020645445614D42 766052927D62927C57C7AF7F7D642C8D733AA1864FB79C6D4B320A1400003B2613A39187655651 271918584D4B221912443D33241B12060000484139746F69312C2613100B0400000B0704090504 030000010000010000060407020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020100 0001000001000100000502000800000800000C00001400002006071F00001B00001C00001F0000 2E000348171B65242A85262A9A2D32B34A4ECA6366BF5F60A24746943C3B98444290403F8D423F 974D4AA55E5AA35D5B904A487D373574302F793738803E409C5859B77173AE646596474A9D4B4D BC676AA955559A4445B25C5BB35D5CBD6A66B86763BB6B64A65750631610843934E19A947B3832 80413A4B1008874E459A64584F160B591F13B17165FDB8A9BB6F619947398C3627A9554AE79E98 A6625F97565060211A72362CC6867DC47F78DE908CFFADADDB8183C8696FE18089F1919CDF828D DC828EF1A1ACDFA2AACA979EE0AFB5FBCCD2F9CCD1F9D0D4F8D1D4E2C0C1E1C2C0E7C8C6F2D3D1 FFE9E7F9DAD8FFEAE7FFE4E2F8D6D4F3D0CEF2CACADDAFB2E0ADB4E2A8B4CE929EE0A2B1FFC4D3 D89AA9A76976A66472C77F8D853445E990A2C8677BE38698B2656FB76E77FCB0BCDD8F9DBE7080 B46779B97083F9B4C7F7B8CBDC9FB1B67C8BB27384DD9AABFFC5D8FFBED4F19EAE97484ECB7C7F A8595EA4555AC27378B06166B6676D7E2F358C3D439E4F55D08187E4959BFFB9BFEA9BA1C07177 9F5258914A50A8676BD5989DB981847442452A00001E00001600003C23263F2D2D332525413738 2822240300001915160400000D04000800004A3F397F7671251E186964604944400C0805030000 0300001514120201000907080D0B0C302E2F4D4542665448644D3F6B55486755473F2E24362920 261C13070000100901120B03180F0A271E179F948E20130B95867F2D20170700004640349A9389 0600007B746E3C37330B060304000003000015110E0602002A29254C4B474D4C470B0A05727770 303F3A000502505C5A5A6362070B0C868686403C3D110D0C0703021817136267610A140B27372C 13291C041C0E15311B2B482C688364364D300F23081B2A13353E2B8F93822C2D1F666354524A3D 72685C978B7D493D2D7A6F5D655847746552A2917F6C5840917D5CA58E64B29B656A5015977A3E B2955BAF915F331600220700725945B29C8F45322B3B29252F221C3D3329645C51190F054E453C 90877E1F18101E170F0E0903201B170A06030300000D0908100E0F050304010002020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001010100070904030500000100030000060000130806 2513132D17194F30354C292D532A306E414893616AAA757DAC747DAF666FD1686FCE555CC44F55 C25155AF4549932F318628288A32309C4846883A367B322C7C373084413B8B484292514B9B5C57 7D403F8446478B494A944E50AC6263C37477BC6A6CA65053C2696BA34A4CB95F5FAE5454BD6563 CE7976C5706BC3706A99494271221DD489839D5650622219783C327D4439E0A79C6B31264F1308 CA887CF2AD9EB5675A853224B0584AEA968BB8736CAE716CAD726AC0857DD99F94EDB1A7FCB8AF FCB1ABF4A09EC16769A8494FBC5B64CF6F7AD0747FD07680C87B85E9ADB5EDBCC2FBCAD0FACDD2 F2C8CCEDC6C9E9C5C7E1BFC0DFBFC0E0C2C2E6C8C8F5D7D7EFD1D1FFE4E2FFE6E6FFDFDEFFECED FDD0D3E7B4B9D79FA8EFB1BEFFC1CFFAB7C8FFCBDCFFD0DEEAA8B6C7808EF6ACB9D17F8DF79CAB EE8B9DEF91A1BD6C75E0939DC97984B36370B56475E192A5FFBED2F5B0C2AD6E7FD197A6E5ACBB DFA5B4E6A7B8F6B1C3E198ABB86B7B8B3E46E19599D6898FFFBDC3EFA2A8984B51FEB1B9B0636B 9F525AB4676F853840D3868EDF929AE0939BFFB5BDFFB9C0A4636961262A4A13166F3D3EBE9293 C29B9C9373745238371501020B0000120606060000040000221E1F1611153733321109063D342F 7B726D19110E312C285D5956110D0C2524220C0B090100000100000100001B17160E0A095D5958 43393769585057433865534955473C1609011F160F0600000B06000500000904000B0300372E29 776C661B0E0694857E0A00000600004D493E716D640804008F8A84221F1A0703000E0A090B0706 0201000100000706021E1D194A4B45373832222721909B973844420D18145A63601014132A2A28 666563393532322E2B0E0D0872736D6B6E65353D321F291E2D392D0615021F2F1293A482384726 051000444A3063654F868370615C49696252665D4C897D6D786B5A897C6B7568558073608A7E68 A193796251339B8961B9A573B89F66664D0D8E7032C1A2699E7E4D2F0F00533417C0A48F776052 3C281F47342D4F3E367D71650C02005A4E427F756B20160C5D544B635A534C453F28231F0A0502 030000030000010000010000010002020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 0101010001000002000000000201001D15134034345B4B4C665052694C507E5B61926A72976C73 96646D98656EA5707ABF7782C35963DF6770EB7780E87980DE757AD57275C76D6DBA6666A15351 8F48447E3A3772332E6E312C773C368E5450A46A66925B587C4241793C3B8F4D4E9A54549F5355 C16F71EF999CE58C8EDF8587E38989BC62629A4240984340AB5651CC7772D37E79AA575164150E C37A7398554C57180F6E3429E2A89CC2887C622417E8A698EBA395B26356D27C6FF1978CDE8A7F BD78719A5D58955A52AC7169D1978CCE9288955249752A246D1C19943C3BC86C6FDF8388E48990 FEA7AFFFBFC7FFB7BEF3B7BFFECBD2FBCAD0EDBEC4E4B7BCD3AAAECAA3A6D1AFB0E7C5C6E4C4C5 E0C2C2E1C3C3E2C2C5ECCCCDEDCDD0ECC8CAF6C9CEF6C5CBFFD6E1E1A5B1955361995466CB8496 E6A1B3FFC7D6FFCBD8DD95A1C0727FEB95A2EA8E9BF792A0F2909DDF8994F1A0A9F39FACDA8693 F4A0B0FFC7D9F3A6B8A96274D697A8D89FAED6A0AED19BA9D69DACE0A3B3E09DAED8919FF6AAB4 FDB0B6DE9199E598A0F8ABB3691E25B2676EDE959C7C333AC27980EAA1A8863D44AD646B954C53 772E35D8969AFCC1C5BB898A8C5C5C71454670494A482927543A397964635E4E4E594D4D2E2526 3630302925261C1A1B0A080B0402032B2321877F7C2C242115100D504C491413110100000C0A0B 201E210C0A0B0503040300000300005F5A572A2522675E5950413A8271695D4E471B100A120904 04000013100B0504000504000D0906040000635B583A312C3C2F2984757022150D120B01625E53 4F4B42241F196D6A65100C090C0807191816010000312F303E3D3B11110F00000010110C3B3C37 383A354147459AA3A0454E4B282E2A272C28090B0600010046454077746F2B2821524F489E9B92 3C39300E0C006E6C604546342D3212979F784A502C2627075D5C3E807A60837B64988D79796C5B 887B6A8376657669566C5F4C6A5D4AA99D87A5997F807555776B43B0A273BEAA75C2AC706C5011 7B5D1FCFAF767E5C2C2B0800967458CAAB9745291B4F372B513B30746258302215564A3C7E7266 2D21155E5148796F654C42391F160F060000322D294D4845302C2B0A0607010000060407020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001010101000201050704040404030000050000 0E04050C00000D000012000026090E35141B340F162500051D00001D00002F00004A00006C040D 7D17227A1B23761D23823034974B4DA45E609F5F5FAB716FBF8987C99693BE8D89A474708A5D5A 7D504B7E4E4A885753804B47703433803F3DA75F60B264649F4D4FB25C5DC76E70CA7271E48C8B E68E8CCC7774B25D58943F3AB35A54CD746EA8554D3F00009E584E834339A2665BC98D82F0B4A9 8A4C3FE8A497B46A5D7C2A1EE0887CDD8176C46B63BA716BAF6E6ADA9B94FFC4BCE3A79D96574E 864239D18881FAABA7EA9694E99092DE888BC47276BE6F72C1767AB36E73C0838BC48C95C6919B E0ADB6FFD5DEFFDBE2FCD1D8FFE0E5FCD5DAFEDADEFFDCE0FDD9DDFFDCE3F9D5D9EEC6CEE3BAC0 F2C0C9CC949FD698A7FFC3D4FCB5C7D88FA2BC7386873E51984F60E29AA8F3A7B3B0606BD37C85 DA7D87D8727DB14D59DA808AFCA6AFCA727EE48998EF96A8AC576AFDAEC1CE8799C38495BF8997 D2A0ACF5C5D1FFDEEAFFD4E2EFB5C3DC9CAAFFBAC58A3F46AF636DCC808AFDB1BB7F363FAC636C E099A1C37C82520B11C67F85FFBDC3682328995459A45F6457191C774546BA918FBD95956D4A48 70514F7C635F533E3B0B00001308062D2523342E2E6968666D6B6C55555732323422222276716E 1E191604000044403F42404109090B0C0C0E0000020B0A0F010002131112030000231E1B463E3B 3B312F5348445A4C49786A67150A0806000004000007060410100E000000040402080806030000 8B868212090472655F51423D31241E19120A68655C38352E48453E2D2A250A06030D0C0A151314 1614150A0A0A6A6A6A545452161614000100000100454742373936494E4A6065614045414E534F 0001003E413A22231B686860666259322B216E665B72655C392B2264534B9588777C7654949168 75704A837B57433818716348D0C2A896866F88776392816FA1907E7B6C5740341E847862ADA28C 7F76599B936C88804FAFA46EBFB075B8A364634A0A7D5D20D0AD775833063D1700C19C82987561 5E3E2F593F32644C405A47395848396A5D4D342619776B5D8F83775E544A100600110801635C56 5E59553934310703020300001B1718161415020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 0200010200010000000000000301020703040B05071007081004060D00011A070B18040622090D 3C21265B3E4368494E5E3E43592A325910195400074F00075508104D040B3400002A0000260000 3B090A2C0000220000290302421F1D664341856362987573AA837EAB827CB88983BE8985AB706C 8C4B49833C3A904242873635AB57579C4645B25C5BB25D5AB25F5BCE7B75DC8780DD837BAD534B C36C63B4645B460000B47065B97B70C1857AECB1A3733327B56F6381342AC9776CC36B619C3E34 973D35D0817DFFB9B7FFC0BADD9C96C5857CB7746CB06C63B66D66BD6F6BBB6A67C87776D98988 DB9190DF9B9AEAAAAAEEB2B2F7BAC2F1B3BEE3A7B3EBB3BEFFCDD7FECBD4F4C5CDFFD7DEFFD4DB FFDBE1FFDEE6FFD7DFFFEAF2FFE1E9FFD8E1FECFD9FFCAD7EBAEBEBB788ACE869AFFB6CBFFBDD3 FEB1C5E69CADD38998E89EABFFB5C2E19099A74D56B4555DC86069BB565EE2858FDF858FE48895 C66A79CE7183A74E60C9788BC1788BF6B7C8FFD0DEFFDDE9F6C8D3D0A2ADBB8B97C18D99D296A2 EAA4AEBB6F79C87C86CF868FFFDDE69750587C353DCA848CF3AEB388464A3C0000D08E92FFDDE1 7433378D4C50C3888A7C504F3D1A16704E4C8F706D60474345302B6C5D5A5C514D1E1614040000 0F0E0C14141428282A5152543C3D3F53535554504F0602012521202725262D2D2F1B1C20000004 0B0C10010005000002030102040000372F2D0700006D625E3025216C615F2218170600000D0908 010000070707020305000100000100000100090806837E7B110705897B78120300150802120B03 504D4429261F524F4A0300000804030806070503041B1B1B0000000000007676767B7D7A1A1C19 1719140001002D2C2A62615F0000004D4F4A656A643338311F221963665B525248938F84594F45 47392E927E758D746D5A3D37A68C7DA1916FD2C59997885F6D5E37877453A5927489755A917D65 A8937EBDAB97C6B4A04B3A26594A35A0947E7267516E6848AEAA7B6A673090874CC9BE7EA79452 583F008F6F34B995614720008E6545BD957C8863506443346144367A6051614B3D7A6959372718 A494878E8073281A0F0A000053493F8A8077534A434A433D332E2B15100D030000030000010000 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001080609060105030002040002 0400020600000600000B01020800000A00001101041B0B0C2C191B453234614D4F7C5D62AD7880 8C4D55652830521920440F152F0104240000260002180000150000140000130000130000120000 110000120000210200341209451D155C2F29925D57C38884C6827FA95F5EA15351A35352843330 903F3C9D4C48A95A559849429D4A42AC4F47FFA59DD67C73AD5B50B96C6277312588483C541609 E3A598A46458B56F636F2218A7554A721A10B2544AFFA39CE28C8DAA5C5CB36966A65F5BB46F68 B8736CA15B53FDB4ADFFBAB4FFCAC6FFC1BFE69C99C3827EC38882E2B0A9FFD7D5F2B3BCEDABB9 DB9BA9D597A4E1A5B1E9B1BCF2BCC9FFCCD8E9B7C2EBBCC6EBBBC7DFAFBBFDCDD9F6C6D2F7C5D1 F6C2CFFAC0CFFFCADEFFBBD0DD93AAEEA0B8FFC3D9FFC1D6FFC4D7FFB8C8F3A7B3FFB8C2FFC7CE D98086BB5C62C25A61B24A51C2616ACA6D78C1616F9B3A4BB7596BDB8092FCA9BDDF96A9E9AABB F0BCC9EFC1CCDCB2BCCCA2ACD6ABB5F6C8D2FFDFEADE98A3CB7F8BC27984CB828DECA3AC9F5860 89424ACF8991E6A3AADB9AA05110144C0E11C5878AFFCACDAC6E713500008159576B4C472F120E 351C178F7A754F3E370A0000241B164F4A473E3D39050503000100000002191A1C696A6E5A5B5D 0100005F5B5C0300001513160A090E0B0C110000050002070B0C100101030100001E1916070000 493E3A2D201A5E504D453B3C0600000C060A060407131315000102000205030909040A0A080C0B 3A3A38524E4B2C22207365620D00000D00000C050027241B1D1A13322F2A010000040301040203 0100000303050000021B1D1C1E201F70726F9C9E9B2628232B2C27100C0937333044433F181914 41433E484D46000300484B40646458B3AFA390837A423026664B449E7D768A655FAC8878C4AA87 A38E61A7926789734A8D7551B198797C6247755D43C8AF99C7B19CA18F79382811796A55827660 665C43A59F7D8A88575F5F237A7535C1B8759C8A4851380098783FAB8755542D06BF96789D745E 825B4A54302079594A7D62518972605643349F8F7F645445211404332518776B5F6F655B5E544B 4E453E27201A0904010C07040E0A0B060203050304020001020001020001020001020001020001 020001020001020001020001020001020001020001020001020001020001020001020001020001 020001020001020001020001040001040001040001040001040001040001040001040001040001 040001020001040001020001040001020001040001020001020001020100020001020001020001 0200010200010200010300000300000500010C08090A05090300000400000C06080F06090D0206 0B00030900010A00000C00000A00001100001D00003700054C0F1646071038000339000943141A 4C2528553538583B3D5238393F2526260C0D1700001500001A00001900002B03003B0F0647150E 561F1A6C2F2C7E3A39843D3B9C5050A45656A35553A355519E504CA0554F671E1776261DB9574E C15950C8675EAF584EB3675A934F425C1D0E3C0100BE816FC88775793122883B2B944133D67E72 CF7368963D358D3C39DD9392B8736EBE7D77C88980BB7C73F4B4ABF1ADA4D48B85AC635D813734 8E4743BF7E7ACD928CC28D87C9928FB8727CB36976A8606CAC6875CD8E99EEB2BEEFB7C2DCA8B4 E4B2BDECBDC7F0C2CDE3B5C0FFD1DDECBCC8DFADB9D6A2AFD297A9C98A9DFFCADFFCB4C8D1869B EB9CB2F09EB4FFB1C2F3A2B1F8A8B5E898A1DF8C94F9A2A8E4888DF29296BF5C6194333C9D3D48 E88693BD5D6BBA5C6CF79CADCA7789DE95A6F8BAC9E6B0BEE0B0BCE8BAC5EEC0CBF2C2CEFFCDD9 FFDCE8E19BA6E99DA9CA7A87D88B95FFB7C0D590956A282CB9777BCD888DDC979C8D4C50581D1F 653334A37373ECBABBAF8183300D0B3F221E60474338201C16040030231D5249441F1A16010000 1818164C4E4D1F212008090B24252748494B3B3B3D373536100C0D3735360705080B0A0F1A1B1F 191A1E0000040000020101030604050703001B131059504B1B100C7B716F0600000D070B0A0509 00000217181C0C1011000104000202080C0D1416155F5F5F1511103129273D33310A00000D0200 0D080208080014110A0807020605030100000503040402050000020505070000020001000D0F0E 8E908DA5A7A42A2B2658535025201D3D3A3519181345463E47493E1B1D0F070800413E2DC0B9A7 A99C8B5D4739593D2F846256A37D729D7865BB9D77D1B98B9F875BA48B62B89F77896F4C8C7251 BAA1839C8468705B406C583F9D8B739F90795A4E36948872ACA6846967348282447D7C3CA49C5D 8C7E41483300927644B39267633F1D9A755B835D48583321633F2F8F6E5D7657458D725F9E8775 4836221502004F3E2E8C7C6D97897C92887E453C331108030600000904012521202B2728130F10 010000040000040000040000040000040000040000040000040000050100050100050100050100 050100050100050100050100030200030200050102050102050102050102050102060002060004 060004060004060004080004080004080004080004060004050004060004050004060002050102 0600000501000501000501000302000302000202000202000202000202000C0606040000050100 0F0E0C0000000000000E0C0D0602030D070906000208000215060D0D00050A000216061042292F 4F23227437367F2E356C0F1A62000F5F01115D111D5E23295B2E315D3939603C3C4F28292F0506 2300004018166B403A87514791554A91524985443E813B398840418F4546904549792E32853A3E 863C3D7D3634813C378E4B438A4A4186362DAC3D36B740389D322A72180D64180BA26352B77D69 4C140082442BFBB89E6D2109893721C6715C8D3625AF594AB6685CBF7C73A86F66935F5289584A 8D5D4F9161538D594C864C417B3A349D5853D88E8BFFD0CFFFC2C0DC9694D4938FB97373F3A2A9 DA848FDE8E97F3AAB3FBBAC2FFCBD3F0BDC6F1C3CDFFE2EAF1C9D2FAD5DDFFDEE7FFDBE5FFDEE8 FFD9E3FFD0DAFCCAD6F5C1CEF6BDCCECAEBDE49FB1DE94A5D38595F29FAFEB97A6FFBBC5E18E96 E6949AFAA8ACFFC0C3FFB0B3E89295BA5E63A14248B04F58E98995D47684CB7383CA7789DD93A4 F5B5C5FFCAD8E1ABB9DDA7B5F1B8C7F5B8C8FCBCCDF3AEC0B56D7BE496A3953A4B872F3DE59AA1 E3A3A45016157E4041CD8086DA8A93A462664E1C1D694C484A322EA58787DABABD9D7D802E1012 1500005B45473E2E2E0F04020A05022E2D292424220305020105041315142A2C2B4A4A4A0C0A0B 0705066F6D6E3D3C3A1B1A182F2D2E0806073232326A6A6A4E4E4E171717010000232220010000 3E3A37211D1A4E4946302C29030000040001030102040203030305030303020204020202000000 2828286664653F3D3E2C2827030000100A0A0400000201000001000E0D090F0F0D0000000F0F11 24242616151A0A090E00000401000507070900000212121269696992918F6965627F7A76332E28 4B473C241E126B6555423B28160E001408009F9176EBDABE7D684D82684F6B50359D7F65A28567 AB8F68B89D72A28960DBC299BEA57C472E05A58E65DAC49DB29C772E1A00352202E9D8BC806E56 7969527A69559287698D8B584C4D11C0BF86AEA97289824E473A0DA99771705939583C246D4E39 8D6C5953321F6642329E7B6854311E7F5F4A371B03280E006A543DB6A18C9D8C7C594B3E281E14 0700001B161235312E4844433A3637181415030000080403040000040000040000040000040000 040000040000040000050100050100050100050100050100050100050100050100030200030200 050102050102050102050102060002060002080004080004080004080004080004080004090006 080004060004060004060004060002060002060002060000060000050100050100030200030200 020200020200020200030200040000150D0B050100010000080806060604000000090708080206 11060C16070E1B0A142E1A25402C373B2A3434191E491C176E2B257F232680121D820B1E750617 5000043500002300002C03013307063505055A2424935B5AA973719E676299594F8A463B874139 954E4897504C853E3C7830317A3235863E41752F31732F2E8A46439F5E58A5665DA6675EB3665C BC5147C250469F3A30772016510900480A00642B186E341EB4725AEDA38AA25038832F1797422D B3624FA356467E382C682C216D392C7747397D4F407A4F3F784A3B7C4A3F834D43C98A83C6817C E09695C77979823434B06464ECA2A1AE6060D2797FC0666F9D4A52BD7078FBB8BFB47880D19EA5 EABDC4EEC6CFCEA9B1D2ADB5D9B4BCE3B9C3DBB0BAE7B9C4F5C5D1E9B9C5EAB8C4FFCAD8FFDAE9 FFCAD8EDA5B3F7A6B7F19DACEF97A5CC757EEE97A0E08B92E9979BFFD0D1FFBDBDFFD1D2F59C9E 9D4144C3646CDA7D87C36774C06878CC7B8AD58B9AD18E9FF0B3C2EBB1C0EEB1C1F9B9CAFFBBCE FFBACFEA9FB3E99FAEFFC1D0CA6C7EA84C5BE499A0F0B2B367312F733736C97A80B5646DD39097 5D2F313C29230A00003622237F6669BEA1A5876A6E3C23270F0000514343271F1D050100030301 1113102B302C212524000100292929211F200501021F1B1C0100003D3C3A2524220E0D0B31302E 1817150403012423214F4E4C6362601E1D1B0100002827252423215C5B59010000010000010000 010000010000010000010000010000020001100E0F0100001C1A1B3C3A3B494748100E0F060405 0403011A1B16090A0507070507070500000207070908070C00000400000517161B0B0A0F020204 18181A0000000000003E3D3B696562605B55665F57574F445E5546B3A896988C763B2D13201100 503F21AE997A806C4BB89F813E2506A4896BAE9473947853C1A57D897047CDB48BC0A77E9F875B B8A175A89368B6A07795815CB8A5849F8C6E5D4C328C7A6257453147391C7571429C9D64989663 B2AE7F898258342A06B0A1826A593D4E3820775D467E624D60412CAB8874502D173E1A042A0800 412108A1866BC4AA93644E370F00000D00003A30265851494B46422C28251915142523243D393A 433F403E3A39040000040000040000040000040000040000040000040000050100050100050100 050100050100050100050100050100050100050100050102050102050102050102060002060002 060002060002060004060004060004060004080004060004050004050102050102050102050102 050100050100050100050100050100030200030200030200020200020200030200080000090000 0701010706040404020000000100000500000700000B00001000021F08122E17213A232D432E37 5132374B19106A241A7A1A1B7B0C138D1723A53742B15A60BA7677C08D8AD2A5A0E4B3AFE2AAA9 DB9B9CD39192CB8B8BC58681C4847AC9877BBA7A70A16158995852B06F6BCF8E8CE1A09EC07F7D A767659E5E5CAD6E69B3746DA4655C995A51A05A4EA951439D413293413571291D5F1F136A2E23 763B2D9E5C4CC37767FFD7C4EC9783B15B4A9D4C3B5206004200005F1F1588494084494180473E 753F3569352A713B31955C53BB7F77EBA8A2FCB5B1C57979954546B36364A858598D3F3FC47274 8F363C7B212AB05D65BF727A763038AA6D75C18C94E9BAC2E1B3BED4A9B3E4B8C5F2C4D1FFCFDD D29FAECE98A8DAA4B4D29DADD19BA9CF95A4DE9EAEF8B1C1D38696EA99AAE18D9CCA7280B45A64 DA808AFBA4ACFBA9ADF2A2A3D68888B46463FEAAAAC872739A4147983E47AF5861CF7B88FDAFBD FCB4C2FFC4D5FFCBDAF5B8C8ECADBEF2AFC0FDB4C7EE9FB4B56679DD93A2F2A4B2B35668862B3A B0676EF5B9B98E5B586A302FC1767DB2656DD2949984585927160F0700001D0B0B6F595BAE9497 BCA2A5644E512E1B1D160808362E2C0F0B0A0707050001000E130F2325241A1C1B000000080607 1511121E1A1B03020009080631302E0C0B0904030121201E3C3B3912110F12110F403F3D131210 0A0907010000605F5D1F1E1C060503010000010000010000010000010000010000020001030102 110F100C0A0B151314100E0F01000001000007050618171511120D060702010100080806111113 1515171312170F0E1309080D0000040000040101030D0D0F1B1B1B12121201000026211D69625A 544B422B2316372E1F423725EBDFC97C6E54433319281700877255947F60664C31684F31866B4E A18668AD906E9F835C91754EBFA37B81683F674E25CBB48ABCA77C7D673EA4906BFBE9C53C2909 4B371C68543B99876F7E7055DCD7AF9B986BABA67CA9A47C403612544725A192714D3A1A6B5639 9E85672D12009173577452373513004320046A482DBFA185886D523C220B2610004B3827615142 574A41544B443A332D605C59716D6C534F4E302C2B211D1C0E0A09050100050100050100050100 050100050100050100050100050100050100050100050100050100050100050100050100050100 050100050102050102050102050102060002060002060002060002060004050004060004050004 060004050102030102030200030102030200050100050100050100050100060200060200040300 0403000403010403010403010403010904010400000900011F1617180F100700000700000B0001 0D00010C000011000415000611000014000015000030060A602118964237C25956D15D60D75E65 C6575EA54F50924E4D69373042150F2900002C00003800003B000040000048070354140A66281B 6F33287D4136A56A62D39890D69B95B97F7BAE7470A56A64975C5691554D94554C9D5F54AC6C62 B87668A25948A65D4C6826168A4F41B57C71CA9186E2A39A833D35732318F0998FE48C80A04A3D 84372D763229A86D65B67B759B5A5494514B92514B9D5E57AA6E66BC8078DA9B94F6B5AF9E5753 8238359F5151AE5E5FB86668CF7D7FBF6D6FB35E61CD7478F39CA2FCAAB0EC9FA5E09AA2F5B6BF FFDFE8FFCBD8EBB9C5F0BDCCF9C4D4FAC4D4FFD1E4D69BADDA9BB0E7A8BBD99CAEDC9FB1D494A5 C17C8EF9AEC2D38595C67383C16A7AB85D6CF096A0C76D76D57C82DC878ABA6968B16160AF5F5E A95857AB5A59A24D528C373EA7515AD68490BF717FE8A0AEFDBBC9F0B0C0EDADBDF3B0C1F4ABBE F1A2B7D17C938F3C50DE91A1D789979840505B04146E272FDA9FA1905E5D3E0808813C41C17A82 A2676DBA9293412F2B140B060D0000311D1E725C5E947E809C888A5646472117160601000B0A08 000000090B080002002729286D6D6D0F0D0E0300000A040604000035313004030112110F060503 0504020D0C0A1F1E1C3534320201000100004342400302003433314F4E4C010000080705020001 030102040203050304060405050304050304040203030102010000100E0F312F30161415040203 0200011B1A182D2D2B1E1F1A0707050000000C0C0E1F1F2141404567666B6160652B2A2F0B0B0D 0D0D0F0D0D0D0707050404020302001A150F5C554DA1998E372F22130A00443927584C36CFBFA8 99876F2F1B026F5A3F9F876D5D432A7C6249785C4472573CB29575AA8E69957954D8BC95BB9F78 80673E937A529079507F6942CFB994A6926F83704FA99678B09C81C2B197CEBEA47B7253A19B79 534A29261D0075684672634250401E45330F816A48513915795C3C826442371600583716714E30 9B795D64462C60462D5D442E5C46315A47365848396A5D54887F766E6761423D392D28253A3635 363231161211090504050100050100050100050100050100050100050100050100050100050100 050100050100050100050100050100050100060002060002060002060002060002060002050102 050102050102050102050102030102050102030102050102030102030200020300020200020200 030200030200030200030200040301040301060201060201060201060201060200040300000100 11120D070000110102442E31381F230F00001703050A0000190D0D1F13151D0D10361B2267414C 8B5B699C5B63B9645FB95148A0262589060B87060B7E0B10640C0B4F0E083D0D035A2F26895851 AE7973C88B88D79795D89B98D69994DDA196D3998BC58D80AE796B905C517A483D814F46936158 A5736AA67169A76E67A1665E94554C7D3D3367241B571809632915703924A4715EE8B7A8ECBAAF 945D564504004500008B3633CA716BBD625DB8635CBE756FC5888372413CAC7975DD9998CB7F7F BE7473CA8381DA9492D38D8BBA7472A65F5DB36968BC7070C17373BA686ACE797CB660638D373A BC6669F8A2A5F8A2A5CF7D81EB9FA3C98288E8A7AFEFB1BCF4BAC8E0A6B5FDC2D4FFCADFFFCCE2 FFD4EDEFA7BFEDA1BDE89EB7FFC7DCDC98ADE59DB1A75C70BC6D82C97688D88192E38B99FFCEDA D87C87B0555EAA51576D171ABD6969CF7B7B661713A95B59C97B79D8888BC27177B16067A04E5A C27481DB91A0F7B3C2EFABBAFFC1D0FFC7D8FDAEC1EE96ACDF8199CC7085EC9EACE599A6BD6978 7C2C3967262CD19A9D986868370506400207AE70757B474BA985855B4945211813080000100000 1907074836366353544D414148403E1C1815030200000000060805000100202020494949605C5D 0D0709060000180F120300000100000706040100000100000807050100001A1917181715050402 1F1E1C090806585755100F0D0908060100000100000402030705060A08090A0809080607050304 0301021D1B1C4B494A4C4A4B2B292A0100000D0B0C0806070100000000000001000202000A0A08 0E0E1005050705040915141928272C7372779090925757592B2B2B3F3F3D3A3A38060500040000 150E04787065E2DBCB3D34232F24124539239B8B74CBB9A3735F472B1500AB937BA78C77755944 6B4C3A62432E7A5B3E755735593B19C2A6816E522DBBA27ABEA47F8F7751B19B74EBD5B0705C39 A59170C9B6968C795B766345AF9E848B7F6744392335291167593ED5C6A778684652401A4A370F 4E380F897248876B44240600684822694825805D3D805E427B60455E442D59402A5B4633594637 69594C665A4E3E352C524B45514C48645F5C6D68653F3B3A030000030000060201060201060201 060201060201060201060201060201050100050100050100050100050100050100050100050100 060002060002060002060002060002060002050102050102050102050102030102030102030102 030200030102030200020300020300020300020300020200020200030200030200050402050402 0703020703020703020802020803000703000203000D0C080800000E0000381B2054353B371A1F 1100000E00002717174A3A3A5D474963404661323C622534691C266400007D0200900508A81B21 D14A51E77376E18B8AD99D95D5AB9FB79387A078709669638A57536D3A364D1C173B09022C0000 3400004813056C382B8C5A4F9A6C5F996A6094655B87574D5C2A1F3903003900004808005F1B12 853F35A96759B57B67E4B09AF4C4B0B586768C5C5258211A360000964C49984442E38B89B65D59 B4635F3F0000955E59A67A779C6C6AAF6B6CAE6060B46666CF8383EDA1A1E99F9EBF7574964C4B 722827843A39A95D5DC17172BB696BA24C4FAB5256E78E90A34D4E6F1B1BE59395D98A8FFBB2B9 F0AAB4FFCAD6EBABBBC38394F0ACC1F8B2CAFFC4DFFFB5D2DD8AA8C87191AA5572F4A6BEAE6378 FFB7CDF1A2B7D17E92EF9AADFFB5C7FFAEBDA24653C46972A84D5491363B6910129B4544CA7473 9D4C49530805D78D8AF2A3A6A45359FBAAB1C877809F4F5CBA6E7BD88E9DD08896EEA1B3FCABBC E990A6CE6C83BA526BBC596EDA8998DF95A2D88A97A9606B80434AD2A0A1A57779592B2D350003 7D464B885A5D7351526D5B592C231E1208062016140800000C01000D03023129271B1714363531 1C1C1A0A0A080001000507040000000D0B0C504A4C372E311C11154E45481C18170100000B0A08 1B1A1801000012110F16151301000001000015141201000018171521201E0100000B0A08020100 0100000200010503040806070806070604050301020100000100000301021E1C1D3D3B3C110F10 01000001000013121011110F07080300000000000000000202020407060B0B0A0F050409161618 49494B7676767878766C6D686E6F6A75756D1D190E0600000D0500847B6CBFB4A25F523F3D2E19 6C5B4794826CAF9A85432A165B422E836656705343452518644531A7886CCDAF8D846644785A38 4B2D0B8A6E49917550A38964DEC6A0C1AB86B39D78AD9976B19D7C7B68489F8C6CA49377B2A390 837363B5A691B0A087AB9A7C2E1C004B3810735E337A63378D75495D4217694C2473522F8F6E4D B794766B4C303A1E06230A0049331E75604D66554564544772665A695F55574E476059534E4643 201B180C060614100F14100F060201060201060201060201060201060201060201060201050100 050100050100050100050100050100050100050100060002080002080002080002060002060002 050100050100050100050100030200030200020200020300020200020300030200030200030200 0302000203000203000202000202000503040503040703020703020803000A02000A02000A0200 1008060700000E00001301010F0000341A1D4B2E322205071B00001500001F0000330C0F310208 2600003A00066E1821C95153EE5F61FF666EFE6672EB5F6AB843497622224C130C260400170000 1600001900001B00001A000033150D57352B87554A996055945E527341365020143C0E01330500 2D0000350500501C0F834A3FB6776ECD8980C87F78C57870C77D72FFBDAAE6A9947E4532A46F5F 825045270000884C44BE79726D201AF0A09996433DBB6E688A4945380300714846B28582CF8B8C BE6F72994A4D823336914245BB6F71E09697EFA7A8FFB9B7DF9997BA7371883E3D641413994545 DE8587CA7173B96364DC88889B494B8B3C3FBA6F74C37A83C27C87964F5FE39AAEFBB0C7EE9EB9 FFC2DFFCA3C3E88DAEE182A4CA6D8CEC96B1A25067D9859DE692A9CA7288D37A8EE78EA0FA9FAE BF6370C56A73BC61689A3F447C23258B3332DA8281A5514F9247447F3532E7989BA7565C9B4850 F4A1ABED9BA9DC8999BD6C7BC47382E893A6F59AACEE8AA2D0647CA8334EA63A52C87585BC7681 B06A7593515B753E44BE90929A70726F4547390B0E47181E8F666A65474983716F362D280C0401 0400001E161306000016110E0A060318171310110C272725010300080A07040603000000060405 0600022D2427170C103D3437625E5D2E2D2B0100001F1E1C2F2E2C0100000100000E0D0B010000 0403011817150B0A080F0E0C010000010000030200010000010000020001030102030102030102 0301020301020E0C0D0604050100000100000100000C0A0B0705060100000000000001000A0A08 10100E0404060707090B0B0D00000201010314141600000000000043443F5B5C565A5B558F8F85 A49E925C5545201708191000B4A997B0A3906F604B42311D95836FB5A08DBDA3925036258E7163 83665876564B957566C0A185C4A384C3A2839D7F5DB39573AC8F6DB39674947A57B399768E7652 9F8964B09977A18A68D7C3A2D4C09F988567BDAC98DCCBBB9685718372589B8B697C6A4299865B 422D005D47183119006E522A6B4F2A7D5E3F8A6B4F4A271154341F6F543F76604B8C7762927F6E 8B7A6A8A7A6D776B5F51473D6057503B342E18100D0A0502060000040000030000060201060201 060201060201060201060201060201060201050100050100050100050100050100050100050100 050100080002080002080002080002060002060002060000050100050100050100050100030200 030200020300030200030200050200050200050200030200030200020300020200020200050304 0503040703020802020A02000B01000B01000E00001200011200001404041406050A00000B0000 2B16155B3F3E1B00002B0000561F258D5057BA7B83CC8D95C4858DC57379D35A5FD4434ABA222E A7131FA21C278A1B22590D0D370601290C04301C13321912381B17644542997C78947D7772554D 5829213C03002700002600002B00003A0A00683A2D9F6F63BC887BD9A397E2A69CC5857CAC665E B56A64D3847FE8958DB362519F513DCB867687493A290000764034C48B80A4685D975348DD9589 8C42378A443AFFC5BD5A28214F26228C5F5CB17171C87E7FC67A7EA85C5E9347499C5253B26A6B BD7978D4938FA1625D8F4E4AC37F7CDC918EDE8E8DD47B7D872E30A75150C77371C97877BB6B6E A2555BD98D97B46A7793495AA3546ABB6882B9637EFFB3D2F697B7F08CAEE782A4D26E90FFB7D2 E48CA4D37B93EF97ADF69DB1BB62748B3343B05564FFAAB6A0464FEF969C983F43802729A24A49 CE7675BC6866853A37C177745F0F10C775798C373E7D2531F19BA8F39CACEB94A5F097A9F093A6 C76479AE4059A12B459D1E3BC14C66B4607089475164272F5922285F3134BA9293A78081947072 451E21250105613E42593F4082706E4F46413F3A362C29240300000F0C0703000017161240413C 3435300406031E201D0507040001001513140300000600020F060913080C30272A0703023B3A38 171614010000302F2D12110F0100000100000403010100000100000F0E0C010000100F0D010000 0201000503040301020100000100000100000200010503040705060100000B090A242223312F30 2220211412130B090A0100000000000809042323211F1F1F000002000002111113060608050507 1010103232302728230203001F201844453D2F2F23423C2EB4AD9B938A79443C29201501AA9E88 6D5E4968564286715E5D4634684E3FA68A7C85675C63453A603F36876657836148A98869977657 674627A68564B49674AF916FB194728D704EB197749B835F604A25B19A78C7B08EC8B18FBCA788 82705A43311D3F2E147D6C4E9D8B678E7B51311C004A3506553F1090794D947A559F82628E7058 6E4D3C5331255E3E31644A396D584564523E5443314A3A2A36261727190E2D20171E140B1D140D 1E15101E16131D18151A14140E0A09050100050100050100050100050100050100050100050100 050100050100050100050100050100050100050100050100080002080004080002080002080002 0701030802020903030601000601000400000300000502000504000603000300000804000D0600 0703000702000B08030302000100000604050100000A0809060203070101140C0A0C0201080000 1E0A0B1600001900001602030A0200000100050500150A04290D0A612F3286434AC77581B55F6C B4646D995258511515380000740A0CAA292EBC343ECF4B58CE5864AA4B53824243582F2B6A514C 725F59A286859F7F82734F5348282B1D03041500002400002900005D26217F4841A06B63D49F97 DCA89DD7A398E2A99ECB8F8597574E66211AC17872EEA09C984744852C26CA6257EC8576893022 3C00006E3023B07B6DDFAB9D683524B07766CF9280D091809D5E4FC88E82DBA79C4A1D17471713 622626BC7A7BB46D71F8B0B3D68E91BD7779BB7A78C88B88C98F8BCD9691A76E67A76A65CD8883 A85A589A4445E48B8DD6807FA04C4AAC5B5AD08081DD8E93974A526F212E752737C7738ACF7992 FEA4BEFE9FBDB44F6FDC7495C45B7CBC5573F090ABE4869EFFBFD6FFB5CAED91A6A2495B832B3B CC7482B8606CA85159D47D83AB5558A04A4B943E3FAD5758E49090A25452974C499C4A4C812C31 CA7079963A47741827D57988F497A9E88A9CFFAEC2D56980BF4963D65772A9203EC64C659E4A59 995C64642F372400009B7477B391924D2D2E8F7173A0838524070B22080B654C4F3D292A766B69 110E095655504C4B460001000506011B1C17141611393B3630322F00010000010010120F060405 0300000B05070B05070D04071812143B37360201000100000C0B090201000A0907171614040301 0201000201000201000201000201000201000201000201000200010100000100000503040D0B0C 0F0D0E0907080100000301020100001513143634353230310F0D0E0100000C0A0B0E0E0C020200 00000000000004040613131539393B5F5F6166666652525241413F51524D595A543031291C1D15 3E3E323A34264E47359F9685ABA3902B200C362A14B0A18C84725C503B268972605C423374584A 83655A78584D75534A9B7A6B502C12AF8C6C9A77576A4928A68566AE8F70A48566866949A48767 C5AB8A6C5231917957AA927070593797815C8874534C381D513D229F8C6C8A78548C794F6D5B2D 6B56298B7647968156775F395E4526462A122D1000300F0832100F1C0000180200130000190800 2D1C0C3D2D1E49392A54463B5F52495C5249665D5669605B5E565355504D504A4A3F3B3A050100 050100050100050100050100050100050100050100050100050100050100050100050100050100 0501000501000A01060900050900030800020800020900030900010A01020901000D0502100805 0E06030904000904000C0701110A020900000C02000800000800000E0701080300030000060405 0503040E0A0B0802040800001107080D01010F010027131456363B28080D0E0000160B07120F06 08040033241D7A5B588A5658995258400000610711741F26A152577C3837500907A147468D2627 9A2B328318206708103E00002800008462608D75737B636348252B1D00001F00001E00001C0000 522E307545458A5452B47F7BC48F8BC28B86DBA49DE5ACA5C78C847E3F384909006E2922FBB4AE D188826E201CA35352D37873E46F66DB62578D251A7D271AC88477B57D6EBD8E7C370A00E8B8A2 CC9882CF9581B87E6ABC8274FBC5B98A5A503B0A053C09065D2524EFB1B2D89899BF7A7DCF8D8E C588878046428A5851A9787199675EBA817ABD7A74BB6D6BC76E70AD5353A24D4ABF6C68E18D8D DD8B8DDB8A90A5555E9F4D59C87585E994A7B25A70B65A73DD7D98A7435FD66D8BE87D9BCE6681 FF9BB3FB9CB2C16276DC7F92D4798ABC6474F09AA79A4751A04D55D9868EAB595F7D2B2FCA787A 9442446F1A1DF9A7A99547459F514FAF5D5FC97278953A43E38691A143518A2C3CCA6C7CF695A6 D56E83F6899EF9819AEA6882FF7D9AE46880A2505E70393F2D0307210000B193939376781F0204 462C2F311D1E8C7A7A1804065F494B372324695959443F3B0001001D1E1832352E00010012140F 2B2D2800010050524F181A170103000C0E0B0000000D0B0C030000080405040000120C0E070302 0403010C0B090504020100000F0E0C171614010000020100020100020100020100020100020100 020100020100030102020001020001030102040203040203020001010000070506020001010000 0200010806070A08090402030100000C0C0A0909070909090A0A0A050507040406131315272729 7474746B6B6994959094958F52534B44463B5052472E2F213A3424463F2C362E1B7F7460A59983 5D4E37695942BDAB957F6A557259458267568A6D5F5D3D30735348745248B89484714E32A17D5B 9F7B59704D2DEAC7A7D7B69783624388694ACAAB8C634626907353BEA483A187667C6442634B29 87704EC6B2919481609D8B6599875FD8C59AC3B1839684567D6A3F6E5831624B29462E142E1403 26090120020224050B3215172A160B3F2E1E5241315A493965554675655676685B6D5F5470635A 786E657C716B6B625D4B4340302B282A2627050100050100050100050100050100050100050100 0501000501000501000501000501000501000501000501000501000B02070A0106090005090005 0800020900030900010B01020D03020C02000B00000900000800000800000B0000100300110000 1604000C00000A00001005010E06040600000703040601050B060A0701030700000C02030A0000 0E00001D0E0B1606064030304634321F0A091700003E201E5532304B22203A08072900004D0B0C 772D2E9A4A4B903A3D9E4446A14B4C6019136C27205608085304073700003A00017A5252765858 3B21221600002500003B0110501021844556935D6B7D4B54A37275D9A7A8DAA8A7DDAAA9EFB7B6 B97F7D672A274405003D0000B36E69FCB5B17D3632722B27B9726EDC9291D77E7AB93E39C74640 AB3C35FAA097954F43DBA394673826683E28E5B79FA8765DAD755EC288726F3424F2BAADAC786D 794841582B28BE918E3C0908AF7574DFA1A2B27574DCA2A088534F582921380C0373443A9B665E 8F4C46AD5D5CB45859DA7A7CCD75738D3A36BD6969F3A1A3E9979BCF7E85DE8B95BD6976A44D5D 761D2FCB6E83E28399A23F54E57F95DF778ED97188E07A8FCB687ADA7C8CB55968AA5260E18B96 C3727BC3747AAD5E64D4878D85393D904146CA7B7E954548671519F5A5A8873939B96B699E4C4E BF686ECA7079983C47D87C89B55966832734E18391DE798BCA5D70BC455BEF6F86FC738DB63F55 8C3E4B8251554828293A2220BAA5A487717332191D2915170B000021171628181B25111350373B 4A36384F4A46282923373A330A0F080F140E00020032342F12140F040603484A4710120F000100 0000000606060100000D0B0C0D090A3F3B3C1B1A180B0A08010000010000060503161513181715 0F0E0C020100020100020100020100020100020100020100020100030102040203040203010000 010000010000010000030102020001010000010000010000010000090708070506010000060604 0D0D0B13131311111109090B0303050303050606080202021313110B0C07393A3482837B66685D 4345387879697B76639E96839085738378646F634D594A33675740614F37A28E76321903876C57 4124125A3A2B7D5D505F3D3195725F684326926E4A805C38704E2BB79474876647C1A081CFB093 6E4F326F5234A98C6E8065479C8163B399786147269E8664917D5895835DAF9D75C5B489FFFFD4 FFEEC3B8A77C76643E513D1C453015614A38846C607C635F71575A795E677E65696F5D536F5F50 6F5F506A5A4B6757486858496C5C4F6D5F544E40373A2D252D221C3027222D2522191411090506 060201060201060201060201060201060201060201060201060201060201060201060201060201 0602010602010602010701050900050900050900050900030B00040C02030E02020B00000A0000 0C00001203001607021405000F00000F0000250F042810041905000E00001102001105050C0203 0802040802060A04080B02050C02030F03050F01000D00000C01000D0C0706030020110E4A2C2C 4B21232800002300002300002800004E1F196E3C336E322A8B3D3BB35758A6393FA94649450900 32020050150F480B084A100F7545455533311400001800002C03096A303E97526492495C692234 6D303FBB8891D1A4A9E0B6B8D8AAAC936162652F2F652929521212390000BC7674DA938F540E0C AA6663BC7B77E0A09EBB7B7958090584110E8C0F0BED827CE2898197534AE1AC9E471808966956 C4947E905C468A503ADC9F8C3B0000CD9387AC786DB3847EA27B7676504D986A6A541E1E95595B CF9393B37B7AD4A19DC599903F140B360A0035000069241FD37F7FD87377A84145C96E6DF8A3A0 F9A3A4DA8588F09BA0DF8D93CE7B83B8626DA7515EB25A68C76A7CEC8E9ED37283E58495E58294 C45F6FB5505EDB7986A949559D414CEA949DD28188914248ECA1A6BC7478AA62666B2327C27A7E A95E6395484E74252BDF93979F5554904542AB5B5C9E4C4EEC959D87303898414AEF97A3D07884 953B47AB4B59E47E8CE06F81D96073B7334AE47083A35A654C22241E0906887A77DED0CF322223 17020769595C1711110C080724181A210E122D1217210B0E605855191A1432352E171C15000200 0002002A2C2715171200010030322F3E403D0A0C09181A190001000404040000000F0F0F2E2E2E 4C4B49373634100F0D010000060503060503010000070604020100020100020100020100020100 020100020100020100010000030102030102020001010000020001040203070506010000010000 0604050E0C0D0A08090200010907081816170404020C0C0A0F0F0F0A0A0A050507040406050507 040404030301000100090A0401020013150A7173669193854647374C4533958D78B8AD99B5AA94 9E8F7883755B6A58403622096650387E664E543A235135202E0F004E2F1D704F40B794809D7957 B6906BAA845F9B7753D0AC8AA78464AB886AB08E7255331865462A46270B85684AAF92749A7F61 B196788D7553917D58C7B58FCCBA9497855FAF9D77907E5A8E7B5A806D4D6C583F3E2C16261304 1D09001B06033B2527553E44463234514038584B3B5D4D3E5A4A3B5B4B3C6252436252455B4B3E 4C3B31392B22251810160D08080000040000080405060201060201060201060201060201060201 060201060201060201060201060201060201060201060201060201060201050003050003080004 0900050B00040D02061004061305053323232816161905040E00000F00001300002A1510432A25 3F21174123182C11081300001100001404040F03050C01050F060B0B02070B02050D03040E0204 1305041404040B0200000900050C040F01001E00004912187031396E30355018196B3E3880584E 310A003E0A009449437B19189D242BAB3E412D00002400003400003600003B0503250000190000 492A277A565691626880414C4D05136E2431C37D88DCA5ABDDB0B3C4A2A36D4D50441D20532629 784446470C0E2D00009E5A59B670707E3836D59190C68684D69C989B66622600004B0C07550000 A13532F39691974843DE9F9A945D564C1A0FA67567B076689557486D2B1BF3B1A14E1003884F44 C391887E534DCFAEA962413C6138367C49483B0002955959E4AAA9D9A6A2D4A89FCBA0974B1C12 2B00008C413E64080B9D3036E4757CC26464C5706DBB6566C47070E89396D47F84E79299F59FA8 9D4750C26A76FFBBC4E48A94B35762D77C85943741791A22B857609F3E47A04149BE656BCC7A80 9E4F54EEA6A9E29C9EB06E709250525C1A1CD28D92A0595F9E555C560B12D58D91B36D6B6F2A25 9C5251C37777BC6B71D6858B76252C9A4950BA6B71AF5E65802A339C3F4AB04A57CD5F6CD05768 8A212FAE6B726541411C0F097E7B74B3ABA83C3030241417170B0F3A3A3A212322060000715E62 26090E270C11180E0C21221C01040031362F080A05030500070904000100161815000100424441 1F211E2527260408070406050001000001000001000E0E0C3635332B2A28010000010000020100 010000010000020100020100020100020100020100020100020100020100020001010000010000 0301020503040604050402030200010604050301020503040907080402030100000907081C1A1B 04040208080606060600000000000200000200000000000013131105060100010010110917190E 03050016180A545543564F3C1A12000F0400473C267E6F58A6987EA9987E735F447E694EA1896F AC92798A6E563D1E093313002B08007C5840704A266F4A2068421B9D7A547C58365633138B684A 613F2378563B64442B8F6F568062466E50346245274F3416A08768988461917E5D71613F645433 B6A587A392767E6D534F3D272B1905584737412F230E00000E00001200001B07063B292521130A 44382A594B3E5244375444355545363826180D00002E1D133A2C234B3E36554C4558504D514C49 433F40070302070302070302070302070302070302070302070302070302070302070302070302 0703020703020703020703040600040600040800040900050C01050E0204120306140405372525 362221321D1A28100E1600001200002307043E211B4F2A21542F263C1B121B0000130000170304 1303060E02060E030B0800060D02080B00040A00000F01001B0907100501070802060701100200 2204043C0F125C282A7B45458D57554D1C15532319602C1F3F0000822F298B2725CD565A670000 4401003201004E130B7435303E0201430D0B956C6875504A572F2D38070A703139BB757DE3A0A7 F0B5B7AD84805437311901010F000054363860393C2C00002B0000632324AF6B6C985254E19D9C E0A09EC288848E5D582400001900002F0000671915F6A19E8E43408B4746E9AFAE3D070557201D BC817B99564EA15B515E150CE9A3997D3D33410800FCCBC6704944AE918BAF928E1C0000421011 985D61935558A86E6DCA9591CB9E98E3B7AEC08E856F302B63121179141ACC545E96212AAA4849 C16967A74F4E802A2B933D40A85356D88388C77279FFAFB6FCA7AEBA656CAE595ED68083C67073 9C4345A54B4D78181CAD4D51A8494DD57C80742224DA9091B77173FBBBBBBA7C7D6E3232743639 D6959B9C5960A6606A47000AC17C81BE7E7C5C1D16904C499E5856B3696AD2878BA95E637B3337 762F33B97175AB5E6486343A7419209A363ED2646F7E1E2953161B36181629241EC4C7C0868581 140E0E372B2F61585B0E1414474D4D0B05094A373D64434C2003083F353324251F0D1009000200 31332E000100000100080A050406030001002426232D2F2C090D0C1216150001000E1412000200 0105040000000807050A09070100000403010605030403010D0C0A020100020100020100020100 020100020100020100020100030102020001010000020001040203030102010000010000010000 0503040503040200010503040B090A090708010000020200010100000000000000010103010103 03030304040407070520211C48494373756A8385786B6D5F5A5D4C67665479725F8D85707E735D 7D71599A8C728E7E64867559AB987A59442750391A896E538C7156AC8C736A4A339F7C66836044 9B7550472000957046C7A17AAE8864BD99797E593C89654BA6846B98765D7F5F4674543B74563C A28468D4B99CC0A789A18C6D84715378674B65543A816F574B39254A3726675646433123231306 68574D97867C4C3B311F11062A190F0D00001A0E0224180C41332667594C8373648B7B6C8E7C6E 9280724B3B2E3022170E0100080000070000110C09191315070302070302070302070302070302 070302070302070302070302070302070302070302070302070302070302070304080307090209 0A01060A01060B00040D01031001041202030E00001A05043B2120573B3A5436343618161A0000 1800004D251D5931274520182100001600001802041603071001060800050E030B1E13191B1014 0A00000A00001806041501001400001703041F100D20130D0D00000E00002003004E231C834641 570C09721A18AE4F4D811D1BB7544F9F3E384A00004100006E2A217B2E28520300883C3C9D5C5A 43100C3F120C6C413BB58480E7ADACD69A9AB27D79623C310F00000E05000E04021D0E11200A0D 2101041D00003501059E6264CA888AC48283AF6F6FDBA19F64332E2B0200160000170000240300 BB847DCA8B86571D1B8C5656BF8B8F260000824648BB76798E4242B96865641310DA8C88C27F79 3B0400E1B6B0C4A39E2D110DD0B4B08058583100008A4D52D496994B0F0F8F5855CC9B96DBAAA3 FDC6BFC884819C4345B54A52A2222F870915851E21721A189F4746AE58596C1619650F12D58085 D07B80BC6A6EC16F71FFAEB0A95857691513CB7775CE7B77761E1C913334A64648B155568A3435 BC6C6DBB7170C1807EA96C6BDDA1A1410706A26668D2959A95565EA2606A4D09149D5C62DDA29E 491007A26560652420BC7877AF6B6CAB696BC080813C0000672728B67475833B3E61111471181C 9F3B439B444A6C35382F1612111109D3DDD46668631A16151A0F13130D112931330009084B464A 311E2498747E33141A1C110F52534D2F322B0002000B0D080001000E100B000100040603000100 181A174143400105041D2321000200060F0C000300020806121210030200010000010000090806 010000010000030200020100020100020100020100020100020100020100020100020001030102 0301020200010100000100000200010402030100000100000301020705060B090A0B090A080607 05030409090901010100000005050508080A0707090A0A0A11111142424033342F2E2F292D2F24 3E40337173658F928182816D938C79706551877B65A99D85AA9C82B0A086B8A78BAF9C7EB39E7F 9D8666A3886B82674A7E5F4393735A815F46765335956F48C09A6DCCA57AD2AD83B7916C704C2A 684326B8947ABF9D84D6B39D9D7D66876750BC9E86C9AB91CEB096F7DDC2CDB79F9D8B75AD9B87 9B8877A695856F5D516250468473694A3931281A110B00002F2114857867786D594B3E2B5A4F3D 796D5F645A4E5B4F415C4E415040313C2C1D412F215543359080738A7C717A6D64564B45251B19 040000040000070302070302070302070302070302070302070302070302070302070302070302 0703020703020703020703020802040E050A0E030B0E01080D00070E00040E0001100000120000 1E06061400001B0000401A19623A38673B385528234817124E19115F2A224F1E192A00001D0000 1F00001E00021A0001160000280B10472A2F43292C1C07061000001608001200002200051B0000 1000000E04000C0800110B00291608482217773831C26C6BA33C3DC35556B246439E393194382B 5F07006B120E8F3534A8504EA4544D671E173F00007E483EC7928AE9B4B0BE86859D62645D2A29 2200001100000402000106000500001509090B00002206052400006E3033E4A2A6944F54AB6A6E DAA2A54616161E00001400001300001E0800886458D89E936F2A23975151DA9C9D5B292C2C0000 904D54D88B918A383ABA6664590401C1706DF3ADAD551D1E663C3EEECECF40231F573833E4BCBC 4E20203C080A4F1919BF89872800006E3C35DCA7A1E5A8A3DA908DC16769D0656B9D212C901B24 7A2020712623370000550707C8787BC17174A15056732228833437E39497D28484944646B66665 82312E490000AA5552C76C6BC86D6C973F3E782726D98F90B36F708B4F4F8E5655E8B2B22A0000 BB8288B77C829E61689D5B654400098A474EE4A8A78D534F703531A86C6BAB6E6D945657AC7072 B4797B793E403A00017D42449052539351535B15176015196D2D2E3810113D2B292E2F27D0DAD1 30322D31302E342B2E0400020208082226274B45496E5B616748507C5D653B2D2D47443F393834 0B0D08000100000100000100080A05000000010300000000323431040807262A29101614000402 000200000201000000050402070604020100010000030200040301030200020100020100020100 0201000201000201000201000201000100000402030705060402030100000100000A0809121011 0C0A0B010000010000060405010000010000090708312F301A1A1A090909000000040404050505 01010105050511110F00000018191443443E6B6C64787A6F6B6D606E70628A88799D9683B5AA96 9D917B63573F685A3F8A7B5E817052715C3F634B2FAB917671563B4D2F1595755CAB896EA68469 6B482A4D2700663F14D8B188FFF8D1A6805C633F1FBD987D6D492F5F3D2465452E775740967860 AB9075C5AA8FD2B79CB39B81B9A58D7A68548D7A697C695AA18F818573674E3C3235241C1E0D05 2D1C1437291E27190C3328167A6F5B857A663C311F25190B574B3F675B4D473B2D3F3124594B3E 5D4D403D2F2213050021140B4339305E55504E46431E1916030000090303080202070101060000 0701010802020903030A04040903030903030903030802020802020701010701010900021D0C14 38232C422D36402B34412C33382127270C111D00021800001C0000200000350000561B156A2923 76312A863D364E0000782D287C3933581D172C00002B0000260000420709622125702E327A3C3F 4B1513200000120000271F0A3B2F21411E241C0000180000200B060F0100291A07614736785142 8C50467528227C1F1AB04944B44C41B34C3D922F18AA4334B5404693242D99403C7A372798644E D7A991E3AE9CB87C729A5456550D186A2B3635030C1900003D3729101D03000C00070000130401 0A00001A0000AA6967DE8C8E8C3A40CB8087DFA3AD3E0F191800002410120300000E08004B2A21 EAAEA38E3726962C1FC95958DD8184280000542626AC5C65D57C827B2A26C27468500000AF5A55 FFBFC36729341C0002D4B2C0AB84871C0000B99390D1ACA62904001B00003C150EA2756F926059 7A3F39D48F8AEA9B97EB91908B2928B54D4EA74C4B7838362C0000440A086F3132803B3E985155 884044884044A25B5F6F282C954F51CB8084D6878A772527762023933A3C852D2CCD7776752524 C47A7B9D5B5DF0B5B95A262AA47377E1B2B8421319BA878EA56E74884B5296535A6F262F7C353B F2B1B7995C61390002B67E8190595CAF787D8851569A6369A56E744F1A202E000069383C66393C 956D6E441D1E230505251515040000A8A9A4E7E8E32322204A46452F2627160D10140E10080002 5243486855597D646A60474D2C171C1D1111322C2C0000000D0C0A121210010000000000080705 00000003020005050300000010100E2929270F0F0D000000030301010000030000030000030000 030000030000030000030000040000040000040000040000040000040000040000040000020100 020100020100020100020100020100020100020100030200010000020100060503040301010000 0100000706040302000504020B0A080C0B09030200010000100F0D28272542413F59585681807C 8E8D8975747064635E72716C858279A39C8CA29783D6CAB2D9CDB3DCCEB1DCCDAE8C7B5D968166 A189716C513C8667536F4E3B96735D9B775F815E42482404421A008A603ACFA783BC9373C59E7F C49F84714D33613F267E5E47997B63BA9F84977D627962438B74547864436A573753432976664F 887861B4A38F8A77667764556A57496A584C7563575D4B415C4B41695B501B0F031004001D1307 6F63575A4E4025190B4034266B5F516B5F514A3E3232281E574D43766D645D564E2F2A240F0C07 16151133322E3B3A380600000701010903030A04040A0404090303080202070101060000070101 0903030B05050B05050903030701010900000E0000170004170006190006260D1330151A36181A 401E1F4C242460302E5117132E0000350000590900832C239C423995342E6306016C1C15813B33 4105003000003B00005F1E1C863B3F8D4145833B3E4A0D0C2E02001F0500302A143C35255F4247 512D37402327351E18392618533E2B553A273A15033500003D00005E0B03C76A62F18F82A94430 A13B22902616800D146000008C312EC4786AEAAA91C88F74995C496E2B22591114310000330001 804E596F515133271B1B1F081615002004001A00002B1508A38273D68F89974140C77B7DB37578 35080F1E00062309120A0000040400342319D0958FCE746C9D2E1B9D2212F06E6EC65E5F2B0000 6A3F39B8666CD97A7E7A261CD17E70450000C96A64FFB0B3D0919C31061A735161E0B6BA542825 613A35DEBBB585675D1600006641389E736CBA837E8B4A466A1F1CD88482F39998D47674923432 A95855905B573E120F653332692E303600004100039B565B9853585C1A1E89484CA76768793739 783135CA7E82C5747A8D3B3DA34F4F550602AF65648D494AD99EA0AF7D805A2D32A0777DD8B0B8 673E46B98C9388555C985D63D6959BA0595F621D22D6959DAD7179260000A06D727D4C50906265 83545A8F606696656B76474D1F00003912175335375A4544645454261C1A151110000000C5C4C2 9B9A980300004A46457D7777110809291F20180C0E0C00003A2A2D5C494D907D812D181D0D0000 4943430C0B0901000001000012110F0A09070100000706040201000706040100000807051D1C1A 0B0A08010000050402030000030000030000030000030000030000030000030000040000040000 040000040000040000040000040000040000020100020100020100020100020100020100020100 0201000100000100000706040B0A080908060605030D0C0A171614030200050402080705080705 0504020403010C0B091716140E0D0B2A292727262431302E4F4E4C3D3C3A2D2C2A55524D473F32 564B39554A3472674BAB9D80AA9B7C9A896B735E43A18872C5A89682625348271656331F411D05 8661465D36176C4421704523CEA5859972538B64477D593F805C448D6D56BF9F88BA9E86A0856A 856E4F654E2F927E5D94825E9585638C7D6086785EB6A68FC4B49DD5C3AFB5A38F7D6A59493627 49362895817626140A2F1E1497898041342C281D173E342B6E6254A396864C40321F130552483C 72685E645B52211A1004000038352E64615C5E5D5841423D32332E30302E0701010A04040E0808 110B0B110B0B0E08080A04040701010701010903030D0707100A0A100A0A0D07070A04040B0100 1404041703021000001000001901011800001A00002802004A1D18652E298A49439F544E88332C 5C0000640200972F26AB3C3394292194382D762A1C2B000038040059271C6A38317D43427A3E40 5C2125230000210000130000181005221B13251015240B11200A0C2B18112E1B0D1B0600270C00 5733234515095D2318874139A45449B55C4E6203009F3C25AA4B399B4643BA6465EA8887F08783 D76C628B291C6210043B00004C110D6E373A622A338C575F5D2C2F2902002005001D0000390000 4A050AD6A79FBC908367271ED28F878C5A532E0B050E00000E00001D0A0C180403180100A4736C F89494961917B23324BA3B2CFF89849536343000008D625BBA6B6ED375756B0F04CC675B7F0A01 C3534FFCA3A5D291995228342A0914F6CCCE9A6D6A260000825D57E4C1BB68433B7E534C64312D 9D605D6D2624792827872F2EB65A5BCF7171E28484AC5B589D605FB7817F470B0B2F00003E0000 560F155811175E191E884A4D995E605820213901024E1315B57979C58586BD77774E0202661B18 924C4CA46465C58E918153569B72784A252CE2BFC69C777EB1889074474E855056CE939994565B 4D1015B2797FCD9A9F290000693F416A4344603C3C825B5E6D46497E555B7B54592D090D160000 270E114A3A3A5B514F5B58531F1E1C1F1E1CD2D1CF84838105010038343359535352494A070000 3E32344236380A00001505085C4C4F3825290A00003731311F1E1C100F0D0100000403010A0907 0100000201000100000807050100000100000D0C0A050402010000060503030000030000030000 030000030000030000030000030000040000040000040000040000040000040000040000040000 0201000201000201000201000201000201000201000201000100000201000908060B0A08080705 070604100F0D1C1B190403010605030605030504020504020807050706040403010100000B0A08 17161412110F100F0D14131115141214110C2A241829200F6159447F755A382D117B6D50746347 8F7B62A68D7790736177574855342344210D401C049D785B9E77585F3714451D009E75558A6344 734C2F846046B28E76CBAB92A4846D997D65BDA287C6AF90DCC5A6AF9B7AC0AC89B19E7DB9AA8D 97896E8D7D6485755E816F5B42301C4F3A29402A1C2C190B5F4B4094827815040063554C8F8279 635950766C621509002F231595897D9E9286392F25271D134D443B4841370D0900090600030000 07060122231E42433E4A4A480802020A04040D0707100A0A0F09090C06060903030600000E0808 0F0909110B0B120C0C110B0B0F09090D07070D05030B00001403001A09022916103420192A0F08 1E00002500002400003B00005910097C29219D4038A33E369A2F259E2C22C84E43C95548BC5848 924430480E003003002A0300552F24673E3A5C30313D10131C00003011161B0708170D0B282320 0B00040A00000D000036231C4832241C02002C0F00916D5D93695B59271C682C22581208823024 62070083200D9C3F2EB36A61CD827DBE58569A2223AD2B29AE332EA53F3A5F0F082B00004B1815 612D2F6831345317176C2F2C300000390000983740EA8D97A2615D622E21C68C818A564B3B1B10 0B00001B180F0502000A00002B0F0B6A3F36FFC1BBC33E41B81F21BE3127E46658DD6E65620D06 370900AE837AB36966CE706E6D0B00CF5F53C43D39C74746FFABABAF6D6F744B51422227B88E8F D1A4A12300001E0000CAA39EDEB2AF5E2D29320000410000C4787AA7525563090B9D4144E88C8D DC8282FFB3B2CB8788995B5CAB6669581115661B224C0108320000702E32A76C6E5623222A0000 471B1A8458575F313195656377413F773634A25C5A975757D99EA0602F3273494B64414727080E DDBEC4D4B5BB9E7D84663E466A3D42D9A8ACA26E727844489F7174C19799492223401E1D765856 2D110E6A4E4D5F41416343467052543E20221B03030B00004339372E2D288A8B8533323062615F ECEBE94A49470F0B0A4541403C3636726C6C1C13141E14153A30310700001105070D01031C0D10 140A0B2D29281615133534322B2A280100000201000D0C0A010000010000080705020100010000 020100020100010000050402040000040000040000040000040000040000040000040000040000 040000040000040000040000040000040000040000020100020100020100020100020100020100 0201000201000302000403010605030504020201000201000706040D0C0A0706040C0B090A0907 0403010403010908060605030100001716141E1D1B3A39374847453E3D3B464543555452514E49 423B336D6558605946665E47978D72998E70B0A086AC987F9C836F785D4AA28575B49382AB8874 866248916C4FA5815F5F38176B4320997050AA8364431E0199765AA7856A43230A5D3D26A58A6F 9E8368A99072897253B09C7B8F7B5A412E0D37280B97896E78684F6D5D44402E181E0C006C5746 341F0E1B05003F2C1E7C6A5E5A493F0D000073655C7E7169443A305C50440A00000F0300544A3E 93897F766E63272016362F27514C463B38311A17120100000001000607020D0D0B090001090001 0A01020A0102090001080000070000060000150C0D140B0C12090A1007080E05060D04050D0405 0D05021309001E12042B1D1042322554403551362B4D2B225A2F2677423A7A3A3174271F792018 8C2A219D3228AF3D33C74E43C44235B43929A23B2885351E450B00330A00270B00432C1E371C15 240805160000180002381E2717030C0F040C2A24281210111B16121306002A160D5D4135583728 3F1B0B4D28188C6458461A0F410D024D0F047226196D15079D3729D67467C2746AB3645F8A2420 7B0503B02B2CBD3738B339386901003E00003100004D1814602B275D1E19803530560000AA4042 E56D77B0424B853735D1988D834F44330B001E0C0017140500020011130813050036140BE6ACA1 E6837DA60A0DEC3F41C23229FA82748D2D213A00004A1C0FC19288AC655FC469646D0500DF635B B61E1DD44645FF9D9BC685817148464D2B2A582E2FF0C4C33F16141E00005E322FF0C0BE794140 3E000046000159090CAF585EAE53589C4347BD6768E79393D08282C57D80914B4D9F5458CC8084 6E1F253B0000410000A362666B34374317162000007356522F120E7458545032301C00009E6665 A76A69B27A7B9563641D00003E1C1D45282D2C1319C0A9AFFFEDF3886F7542252A3F1C22EFC8CD 9B7276704849906C6C917270553936351D1974615D1806023C2A2665524E5D4847675251321C1E 2D1D1D0D030124211C171C158287806262606C6867E9E5E406020124201F423E3D3F39395C5656 2A24240600000A0102160D0E0700000A0102140B0C0B05054541400100001817153E3D3B21201E 080705040301040301010000070604050402010000010000030200020100030200040000040000 040000040000040000040000040000040000040000040000040000040000040000040000040000 0400000201000201000201000201000201000201000201000201000B0A08070604030200010000 0403010504020302000100000A090711100E100F0D060503020100060503070604010000010000 0504020100000A09075C5B5981807E7372707773709C9791A29B916A6454958F797E745B9A8F73 7D6D545240283F29146E5443624535735241AD8A747B573D744F32B89472E0B998CDA68560391A A0795A603B1E502D115D3B2097785C5B3B22674C31553A1F7D6446877051A99272AC98778C7959 58472B8C7C62907F65C1AF97AF9A8555402B927B69776251543E306451437361555B4B3E5F4E44 17090091847B796C63463C3261574D0800000800004B4138584F465049414E473F1D18122E2B26 3834312625210908060100000000001007080E05060C03040B02030A01020A01020B02030C0304 130A0B1108090D04050A01020900010900010A01020B03000800000C03001002001909002A160B 371C114523195C31286631296C2C237F322A9A433A9E3D3489211895261DC24D43BF4435A12C1A B85540A2563E3200002602002F19042514043A2720230E0B230A0E2F182047323B1E0D17180B15 2E272E0100000F0A041302001800003C140A54261947170B3707007C504565392E2D00004D1107 82352BA1443CDD7167D4655C91302A94352F922B267F0E0A9114129B1919AE2E2F8F1B1C700E0D 681915420300390000541007A55049C05753F1797AAF333BAB3E44EA9C98743E34350600240300 0D00000D0600070700171008220E05A97E75FFBDB07A0F05C32522D02827DF544DEA7E72560600 2D0000734337B8837BAD6861A9524B690100E76862A60A0DC73536EF8E88D6958F673A35240000 210000D8B0B0815959200000220000A06E6DF0B6B55C1A1C4D02064B0000953E44EB949ADF8A8F DA8A8DA95F60AD6566894345D68E91974B4F65161BC8797F8B40455F181E7D4143572526441E1B 56393518030033201A4937331C0A082E120F6F423F592321D7A7A7572D2E3816174A2D2F180205 301D218E7D83FFF2F8746167301B20270E12D2B8BB61434556383A795D5C886F6B67544E23140D 3B2E283328221B100A3D302A7364613E2C2A4232322419171C17132829230003005A615A62615F A9A5A4D1CDCC030000312D2C322E2D130D0D2F2929211B1B030000110D0C030000030000080403 2723220501003837350706040100001514122423210E0D0B0100000D0C0A010000040301060503 040301020100030200040301020100050100050100050100050100050100050100050100050100 040000040000040000040000040000040000040000040000020100020100020100020100020100 0201000201000201000D0C0A0908060403010403010B0A08100F0D0A09070100000B0A080F0E0C 0F0E0C0706040100000201000605030807050B0A08030200191816474644444341171614363533 9594908986814642394A47384D4834A29A837C72593E2F1861513AA893808C72617457476D4E3C 9C7C658A684D785535E2BE9CFFE4C2CFAB8BBD9677E8C3A6674428442206A68469816246907258 92775CAF9678886F51B0997AA68F70D1BC9DAA9777B9A88C98886EB1A08663523877624D48331E 7A6351725B495D47397966575D493E5141343D2C221C0E032D2017ADA097645A50463C32473D34 3229200700000D06004F484046413B423D392B2823100F0B050400050402040301000000140B0C 12090A1007080F06070E05060E05060F06070F06070D04050D04050C03040B02030A01020B0203 0B02030C04010C02001B1203221409241407321E1542271E502F28643B3564332E7439336E2924 6A1B16852E279A3B3587241E6A0300710700580000AD5B46E4A28C7747313E1E09402917534032 301C151803021C03061F080E2B161D0F00040F0009150A0E120D09150800270A02330600380000 541109722F2776362D440B026531265F291F7E3E3599463EA13B36CC554FB83933A124229A231F 9D2E276800005C000076070097201C8A1211B64444AE484666110A47000077291CC87265C66054 891C15C95F5FFFBDBC5B1A142300003009021A00002A100F0F0000210D0E1100005F3E39FBCBC1 A45F506E0A00E65C52BD2D25F37E77A249414406002C0000A7706B9E615EBC77728A373177110C E26865AF1D20B22A2CE48B85D2968E84514E1F00001D00007E5A5AC5A1A11B0000210000481816 FEC6C5A4646546000168191E98464C914046EA9EA2B06A6C672727814443B17172854345C57F81 AE6669782D31DB9597BC7A7C5F272850222245232139201C23110D5B4D4A2217150800005E4A49 4F29287448477B5353997776987B7D250F110B000023171B5C5157E9DEE4695E64271B1F3F3035 D9C9CC523F41584445745F5E846F6C73645F0A00000B0400423E35110A040C0300675C5A211312 5648472C222017120F3D3E390003002F342E2E2A29F8F2F2BDB7B7040000110B0B342E2E2C2827 0602014642410B0A080100000100001B1B190000001717152828262F2E2C161211050100030000 0602010B0706030000090504080403030000050100080403050100050100070302040000050100 050100050100050100050100050100050100050100040000040000040000040000040000040000 040000040000020100020100020100020100020100020100020100020100060503070604060503 0706040D0C0A1413110F0E0C050402080705070604070604070604040301010000030200090806 0100002524224E4D4B555452676664A1A09EA6A5A36867654F4E4A504D487D796EA09A8A746D5A 635B44A99D87BEAF9A776453321B0B694D3F82655385674F86674B6D4C2BB69471A48161694628 946F52BD9A7E916E52603E22C1A286BC9E82B2947A91765B7F654ABAA08591795D9880647D684B A99678BAA98D65553B9281672E1D0346311C1D08004D36247B64527C66586F5C4D5E4A3F524235 58473D1A0C010F02002E2118B7ADA4564D444D443D3E372F211A12140D07060000231E1A403B37 25211E0908040302000706040908060808060F06070E05060D04050C03040B02030A01020A0102 0A01020A01020B02030D04050F06071007081007080F06071006051106002E21193B2C253A2922 39241F331A162A0D092A07052300002D00002F00003100003C00004400005504006E1E17601104 782F209F604F9863534D23133413041D01001C04002B0F0C1600001B000017000021070A180205 2411131E0E0E4C3B342A0F062A0000390000470000741D16882F2B600D07752C253600004E0B03 944741DA7D76CD5C58BD3935CA3C3AB424239F1512B83D368C1D12670100720C00972C22AE3D37 AC39349827219F372EA64439B5594ABC6351BD604ECF7462FFB0A8863B35400A00330D042C0D08 1600001800002B060E1F0000370E12D7AEACCD9D93450300933C2BD05C4FBC473DE68984490400 350900240000C98B8C8C4648D08A8A772C29701512C254538201059A2325BF706BD69B959C6261 300000220000210303DDBFBF3213111B00001D0000885554FFD0D0823D40944C4F82373B924A4E 773537A4686A4F1919663332A36D6DA56D6C5B1D1EBE7E7EDA9899723031B07474B88582522927 2B0C09110000473533483A390900003E32345C494B2C0E0C84615F40211F7155547A64663B2B2C 0C00022B2225544E52F0EBEF6C676B040002474145F7EEF151464A211313887473614E4A63544F 0700001410072F2C230A05000A0300392E2C3B2D2C4133325348460F0A0733322E0A0F090D0F0A 3F3939C7BEBF7D74750400000D07070E0808817D7C1D19182928264342400000000B0D0A000100 10120F10120F60605E565553070302040000120E0D0300000501000B07060300000C0807030000 030000090504050100030000070302050100050100050100050100050100050100050100050100 050100040000040000040000040000040000040000040000040000020100020100020100020100 0201000201000201000201000100000302000605030605030A09070F0E0C0C0B09050402050402 0100000100000605030706040100000100000605030201001A1917353432666563888785585755 11100E01000001000017161283807713100106010067614BA19682645542413020755F51886E61 9D8271856953694B2F8566479B7D5B5736174C2A0E6B492D775539A98A6E85664A8D6F53A2876C BEA38893795E70563BC0A88EA89076D6C1A6836E53887459AF9E84A7977DCCBBA1705E4679644F 836E5BA99481A691809F897B4532246351454E3D3365574C0D00000E01000D03004138318A837B 706963322B25120B050400000A05010500001D1916100C09060501070602050402010000000000 0C02030D03040D03040E04050E04050D03040D03040C02030F05060C02030C02030F05060F0506 0B01020A00010D01031002021303031502041200011100001400011900031C00031E00011E0000 300608562528744140753F3D6329284E171444150D40160A340E032904002F0D0444231C522F2B 522F2D5A32332D0305401819401A192200001F02002B140C4F372D55342B46170D480500802B26 9E38349D302BA333317A110D872A25741D168C3730C46760B24540B93936BB2A27B61D18C42C27 C8352EAC211AC5463D9B2B1F8E2A1B660B007417068D2518A6362ABC4237D3594EB8483AB95A44 ECA285DC9B7F813C2C4204007B4C4237160D1C04001B01042600092E000C34000CB8838DCC9E9E 5E2F27561C10B068596E1608DA867B7C3D382D00001900003D1513D28C967B2B36E9A4A96E2A2B 6D1F1DA64E4D460000721617BB7A76B37C79A9686C632A301D0000130000977F7D806763220501 190000340805C3908DFFCFCE5515164C0C0D4C0E114C15186A393C9B7172411B1A461E1C8A615D 7545437D4A47E6ACABA56B6A854D4CCE9D99976F6D26070438201C4531302C191B2111145A494F 1300036D53545034331A02005944436D5D5D221616150C0D2420215C5A5DF9F7FA72707509070A 6A686BE7E2E608030713090A6856547A6763544542160B0706000025201A0600000D0301130504 4434340B0000554747261C1B322D2A1D1C180C0B072E2526F4EBEC817879060000060000282222 1D19185A56552928262625230B0B09080A070002000106021D221E1416133E3A39433D3D040000 0B05050F09095D5757040000070101060000050000050000060000080202080202060000040000 050100050100050100050100050100050100050100050100050100050100050100050100050100 050100050100050100030200030200030200030200030200030200030200030200050402040301 0302000302000504020706040B0A080D0C0A020100020100020100020100040301070604090806 0B0A081514123B3A38535250403F3D1918160100000100000201001412136867655B5851454135 948E7EABA491807563887B6ABDAD9E857365AA9487695242947B65694F34C3A88A896F4E6C4E32 4E2E15BEA08645270BC1A389896E5392775C8A7057967C638B7359937B615741299A846CB19D84 A18D759B897184745BA4967CC5B59C6E5E477E6C567765517F6C5B887566826F614733284F3D31 5F4E4456483F4D40380A0000150B020C05003C3731807B774F4A463B36320D08050400000F0B08 0D09080300000100000504020908060100000100000E04050E04050E04050F05060F05060E0405 0E04050E04050F05060C02030C02031006071107080E04050F050613070914030918040D19050E 18040F1905101D0713210B17250D1A442D37462C354E303851323849292C381617290708210301 1C07041E0C081D0A061F07052E1211472526572E325A2D3278454A632F3342101140100C6A3F38 6943383413042904005423157C3930802C2299322BC14A44BC3D37B63731C64D459E2F28972E28 AE47409F322BA82D26830000B41D16E5483FE74B3EAB1305D34036D1493DC14B3F882112550000 99412D902F1CB0432FD05545B83A2BD15E4BFFA38AC98361894C2D57130076362A67352C240200 200B061500002F03102B00039B5D6CBC80889565633105009761575B1F147B372AC98D83431714 1900001200005D3639CA828E7C2939D8959C4E12146F2D2E9D5757440000692524A66F6CAE7677 A45E66975A622100010F0000624D4CAA95921700001F0200220000805451EFBEBA9862625C2425 330001280000572F309F7F803317161200002509059D7A766D44408B5B59CE9B98A87773784B48 79514F8A68663D211E2109092A141713000259424C2710185C4648311E1A2A1816463734B0A4A4 3D33320B0505282425525053BEBEC0BCBBC00000046D6D6FC9C9CB0604070C0306816F6F745F5C 412F2D180D09080100342F292F27241006041406051C0A0A1603052A17194F4141150B0A191411 040000968D8EFFF9FA5E55561D14150B02030400000E08083935344743421A1917060604000100 050704000200191B182D2D2B060201312B2B0B05050D0707040000484242484242040000080202 070101050000060000070101080202070101050000050100050100050100050100050100050100 050100050100050100050100050100050100050100050100050100050100030200030200030200 0302000302000302000302000302000504020403010302000302000403010605030908060A0907 0302000403010605030807050908060807050605030504021B1A1812110F050402010000010000 08070521201E3635336B696C6E6A6B47443F5652478A8476908977AAA190E5D9C97B6D608C7C6F 907E72AF9C8D7A6550634E33D9C4A5957E5F7E644B71553FAD937A6D533ABAA0876B5138977F65 BAA28A968068957F67C4B098AD9981C4AF9A73614B9C8A76705E4A0F00006A5B44A3947D7A6955 9E8D798C7B694E3B2C6351434430254D3B310D00005D4F463C2F27584D47180D071209020D0804 0B0803423D3A4945424B4643221E1B14100F050100070302070302030200010000010000030200 0302001006071006070F05060F05060F05060F05061006071006070F05060C02030C0203100607 120809120809140A0B1A0E1214030D1702111604121705151806161B0919200D202413251F0E1E 23132027172225151F1B0C1312030815060B1B10141A1B1D1A1E1F1B161A180B121E070F2A0912 30050F2F0005581F2663282C692D2D4B120B2B00005827166F422D2A00003B00005D0500952F23 B33E34C13E34CA4137BF352AB32D22B2332AB73D328E150A8D1105B73326C13423B92211E04531 D93F27C12B13C3321FC23929BE4334A23224BF5A488A2916B7543DD9735AB04227D5664BFB9275 D9775ABF6A4B86351A832C1B8C3A2F56160D30010012000026110E1D00008F5561CF8D97BB7F81 52251F3B11059661592F0000B47B748B5B571500001703040E00008B6469AC6472843342C3868D 3200006933337C49482600003E110E7B4B4BA0686B7F3742A8667039141B0F0000291413B7A4A0 35221C1D06001E01003B18129F7672DFB3B05A2C2C5B2F306A41454320243114185F494B150603 3526214E36327F605D360E0C6C403DDDB0AD673B382C0402BC99975D3F3D1F02043F2429381D24 684A56452A33332121170906241613291E1ACCC2C1645C5A0400002D2928494546B2B0B1DDDBDE 1C1A1D97959AD1CFD40402071F16197763646A55543826242416130B03002B26224C4441080000 1B0B0C0D0000220E101F0B0D826F731F10131F13150700006B6162DDD3D43026273D3435584F50 150F0F040000130F0E3E3A391514120302000808060808060305020909072525230300000F0909 060000050000040000161010474141352F2F0C0606090303060000060000060000070101070101 060000050100050100050100050100050100050100050100050100050100050100050100050100 050100050100050100050100030200030200030200030200030200030200030200030200050402 0403010302000201000302000403010605030706040403010706040B0A080E0D0B0D0C0A090806 0403010100000C0B09010000010000161513302F2D4443415857556B6A683D383C130D0F3E3935 837C728C86789F98869188773E32223125198C7E73D2C1B77E6E5F5544325C4C33AA9B7E8D7C5E 9E8871755F4A8E7861927C65927C649C866E513D24BBA78F907E66AB99818F7D67867561BBAA98 B2A18F9786766D5E4B5A4E387E725C6357410B00001304006B5B4B5745377E6E612C1A10514038 0B0000372A24584D4742393448413B0500000F0B08060501040000575654211D1C262523060405 0200010604050E0C0D0C0A0B0100000100000402030604051107081006070F05060E04050E0405 0F05061006071107081107080D03040C0203100607120809120809150B0C1C0F16140411140114 14031516051815061915061B190C201E11251B0F23150C1D110918110B17150F1B18121C19161D 1818200E191F101B2113161F140C171B071323031027000B2800015D252E571A1F460908692A23 713326511604602310732F1A7A2113730B00A02F21AF3424BA3524E15544D54836B92C1BBC3323 D85344A723149C1704AC240ED04328C33215E55030EA5431D94625D3472CAC2811B23425D75F51 B544349D301CB95138801B00D26E4CFFC5A0EF8B69BC5536C3593FB84B36C85A4B902920741F18 490A031B0000230600441215E1A0A6BD7276904A483402008B5F524E17124D1613CD9A993F1718 110000301D1F110000B2898F7B3742964E59AC787A2800007949497145441500001C00006B3D3F B97C837129349D5E675E353D17000111000084716D826F691100001F08002005003C1B14E0BAB7 8159593B131485616569494E1B0005594547574D4B2A231D2F1D195D44403B18164D2523AB7F7C A377743D151364413F6243416143453C1F2445272F76556041262F1D0D0D251C171B120D342B26 B8B0AD8D8583140C0A403A3A3C3636C9C3C5EAE5E9353034D9D4DAC0BBC104000531282B342022 584342412F2D281D190901000D0A054944400B03001002020D0000110000331F21806D71403033 190A0D15090B93898AC6BCBD12080923191A4E4546372E2F130A0B0400001F1919231F1E030000 0F0E0C0100000C0B090403010E0D0B0E0808040000060000040000100A0A040000050000575151 0F09090B0505070101050000060000070101070101070101050100050100050100050100050100 050100050100050100050100050100050100050100050100050100050100050100030200030200 030200030200030200030200030200030200040301040301030200020100020100020100030200 0403010605030807050D0C0A0F0E0C0E0D0B0B0A08050402020100010000040301171614282725 2A292722211F201F1D272322312B2D797071675F5C8077709F978A5C55452C2312231A0BB8AEA4 85786F887B7283776B302312655943AEA3877264499F8E7A8A77665C4A3673614DBFAD978B7963 68584156462F86765F776853B7A893BEAF9C4232227C6F5FB6A699766959706553B3AB96605845 0A00001104005A4D3D0C00006F615625170E30211A1A0D070800005F56511F1714494440030000 020100010000010000100E0F0F0D0E0100000E0C0D0301020D0B0C100E0F0A0809010000010000 0503040402031004061004060F03050F03050F03050F03051004061004061307090F03050E0204 100406110507100406130709180B12160A1814071916091B1B0E221B0F231A0E241E1228231A2F 251D321D182C1713241612211A18261D1B2818182211131F0D1520111723161523191120200E1C 2A0E1C310D1B33091345161C3C05083B00007E3D379652476A22136417076E170690291AA33220 B03925AA2D17CB492FD74F35B1270BBC3017D0442DD64A33E0553EC43A1ED04727B32D07BE390E C53C0EF05F32DB4C22C7431DC4492AE26954C44A3B9D1D10EA6C5DBA462DCB6040DE8158E78E64 DC7C56C05135C5402FEA5E51CF473BAB2D21AF43396B190E3B0B00200000AF6E6AC67574AE5350 4A0000571C0C9F6C5B2C0000955A5C946669210003280B104C3235240407C49A9C4F1418AD7274 8D645E2100007A4A4A6E45430E0000110000673335CD8A91753239884D5374465137131D140000 432B2BB9A6A21807001100001B04001500006F4E49D1AAAB4B242738131A3C1822593944614A52 574E4F040000241414210909664443663E3E5529287A514DA47C7A19000026070584666636191D 27091172515C290E17100201261F1917100A4D46409F98928078750D0502342C2A3027289F9697 FFFBFE2F2629E9E3E79690940E070E23181C0D00004A3635493B3A1E16130A07020100003E3A37 1D18151408081808090D00004E393E6653574F3F421C0D103E3234FFFCFD958B8C0A00010D0304 090000443B3C544B4C060000170E0F2620200400000400000802020300000E0A090A0404040000 0D04051108090600000D04050E05060600002B22231108090D0405090001070000080000090001 090001070101050100050100050100050100050100050100050100050100050100050100050100 050100050100050100050100050100030200030200030200030200030200030200030200030200 0403010403010302000201000201000201000201000201000605030807050A09070C0B090C0B09 0B0A0809080607060411100E1F1E1C2524221716140706040403010A0907100C0B3F3639413738 A197955F554C2B2115140B00070000A9A2929B93883B32296C635A3D352A5E57478B84718A846A 615A40897C6BA9998A3F2F1F5C4C3CB5A6939889748677622F230D584C365B4E3B655847928575 97897C473B2F5B4D445E5246615A48867F6C6E67554F4635231A0B4E42361104005D5048251810 0D0200130A05060000342F2B2F2B282723201817151B191A434343020204060608010002121013 0100020100020C0A0B0503040100000100000501020602030400010E02040F0305100406100406 1004061004060F03050E02041307090F03050E02041105071105070F030510040613080E150A18 110819160D1E1F162922192E1F162B221830292138140C231712281A15291714271714251A1826 1C1B291D1C2A1E1D2B1F1D2B201929201324200E1E230B19290B172C0B144821265123256F3A36 7A3B346E241B98463BBD635A932E227C0B0098210DBE462DCA5132C64A28B63611A92401BC3311 FC6F51CC3D1FC33618DD532FE9643BD45624D05720D4591EED662ED14915C9481ED65A38E66953 C54738E86658CC4D3CBE482EFF9875953209700D00B24421A92B12B92519D3362DC93124B12214 C04035A23C304A0900763B2BD68278C8615CAD3E374A0000A35C48470C004D0C06CA8F914D242A 1900003A171E502C304E2627BC908F3A0905B98C866A4D3F1600006736326C403F0E00000F0000 5D2226BF787E7C3E3F713A3F75434F512733190000220507AA95924330290E00001400001B0000 160000BE9A9AC9A2A73109121E000545212F5C424D4C43481812140A00003C23264D2B2C492121 3206053F161298706E502D29160000402423684B4F5134396E4E59250B14080000100B05211C16 524D47A09993655C570700001F1412291D1D44383AE7DBDD4D4246C9BEC4AEA3A9291E26281B22 4734364D3B394C413F0F0A060F0E0900020028292421201C1C14122216160B00005D4A4E4F3C40 3222251F1315675B5DF9EFF04F45460E0405150B0C070000302627534A4B1B121312090A100708 080000060000362D2E060000140B0C070000060000110809060000150C0D060000060000191011 0600000E05060B0203080000080000080000090001090001060000060000050100050100050100 050100050100050100050100050100050100050100050100050100050100050100050100030200 030200030200030200030200030200030200030200030200030200030200030200030200030200 0302000201000504020504020706040807050908060A09070A09070A0907010000060503080705 0100000100000100000605030501002E2327483C3C342925100600080000261D0E8D8676A9A194 1B1308A69F9739322A666257938F83A5A28F727059625D47675E4DB5A99B3325185E5242615443 AA9F8B786D596D624E2C210D3D3522988C7C3D3425382B228D837A4F423A41372E2E28187D7865 5A54443A3323453D306A60561E140B453A34332822070000150D0A07020016120F3332300C0B09 2525251C1C1E4C4C4E3F3F410000021A181B010002060407010002030102010000010000010000 0602030501020400010E02040F030512060814080A14080A1206080F03050E02041206080F0305 0F030512060813070910040611050713080E130D170E0C19161221221E2D24203120182D211930 292138211930282037292136221A2F1F182A211D2C2622312A23331A0F201D0F20211022221020 230E1D230F1B28131C2D161C4C2F3144211F3606024003007B2D299B403BA13936C4534BBD4535 AC341CC24C2EE16D48C24E25B33C11DB5D34EA663FFF845FE55733B62804D1481EC34411DD692C EB803CFFB06AFF8C48CD4C12F57043C74020BE3A25FF8574ED7564A7341FE27355AB3B16CC5431 CF4F2CBC3015E4513FEE544AD4372ED33325B61D0DB12315C44E407B2A15D38571CD5E53E2615B AD241C991F10B55D493400008A433DB77C7E2A0A0F120000461B24451219814F509E6E6A360E02 B69785513F291400006F3C387C4B47180600140000642226AE61678D535165333274404D592637 4016221D00026E545378655E1F0C051000001F06001D00005A3636DEB7BC7E5460754B594D2436 19000953464F4B42472110164D3237240105552D2E360A0B4E22213B140F7D5A562E110D140000 775D5E8C71766C515A1E090E0B03001D1A13423D3745403AA9A29C8F8681190E0A413332201211 160808BBACAFA5969BD1C2C9B0A3AA40333C75686FA79999403231453D3A0605000D1009000200 1116101C1E19100C091A100F0A000079696C4433390A00001A0E1282777BEDE3E43B31320C0203 0B0102070000070000392F304137380900000700001208090A000143393A372D2E0E0405070000 1108090B0203060000110809060000060000170E0F0C03040A0102090001070000080000090001 0A0102090001050000060000050100050100050100050100050100050100050100050100050100 050100050100050100050100050100050100030200030200030200030200030200030200030200 030200030200030200040301040301040301040301040301040301030200040301050402070604 0807050807050706040706040504020908060B0A080C0B090B0A08080705020100040000110507 0A00001709061609001A11028F8675AEA7970B03006D665C625B53231E185E5B528D8B7F666553 47463136341F534B3EB0A69C24180C504738594D3D5F5744877F6C948C7989816E6B645232291A 60584B372D243D342D6F6460483F384C493A63604F454233201A0C110B00463E33443B32241B14 3A312C0600000E06040400000703020D0B0C000000040406000002131217151419000004000002 09090B0000021111130100020806090A08090402030300000501020602030D03040F0506140808 160A0A180A0916080712040110020012040310020211020514080C15080F11060E11050F110916 1716241214231B1A2C272638282739201D301E1B302621371E192F1F172E1A1229170F241D182C 2A2539302B3F2F263926182F29172D29172D2716292310241E0C1C1E0C18230F183721241F0101 471F1D5F2C286D2C2690413C973E389E3C33C85D4BBF5138A33818C95F38DE7347B8491BBC4819 D55A2EF7764EE8653BD45127BE3E0FE26932E37333EB833CF48742E86C30F97242B93006C94320 E26245FF896EDE7255FC9574D56A46CE5C37E05E3CFF7355D44026B9220DE14E3CD43F2BC72D13 D53E21AB1D05B73D25D97A5EDC7C63E06253BF2F26B0160EDE50468B1B0D580000BF716D753D3E 1B0205130003492026330104A06E6F7F4F4B3E130AB392834D38251500007B45437F4C4B120000 1200005D1F22934C508957504E211C79464F501E2A653A441D00003E21239B86834B3832140000 1400001B0000270708AB878BB088906E444E865C682B0B1609000342373D3B242A190000420F16 662B317433393D00022C00004E211E714B481600003E222180676A674E540D00000600002D2A23 4A453F221B15928886C6BBB9382A296658571103031A0E0EC3B4B7E7D8DDFFF7FC66575E4B3A42 D1C2C7DACED020181635312E060501090C050002000D0F0A20211C17131028201E1A0E10B4A8AA 5A4E520D0105281D21A79EA1FFFCFD231A1B0600001007080E05060800005A5152403738090000 0700000C02030700001F13156F65660B00010F05060600000C0606140B0C040000140B0C161010 0600000903030800000500000700000600000A0102080202080000040000050100050100050100 050100050100050100050100050100050100050100050100050100050100050100050100050100 030200030200030200030200030200030200030200030200020100030200040301050402050402 05040205040204030101000003020005040207060408070506050304030103020011100E070604 0100000302000302000201000E0D0B211D1C070000160A0A1B100C070000686055A0988B423C30 817B6F47433A38332D23201B66635C99998F626355474836393826615B4F887F76231B10574D41 443B2C6E65564D4435AEA5969B928362584C1E160B0700005C534C3C332E2C2421463F393E3A2F 4E4C3F504C414E4A3F2B271C0600000A0300120B054038350E09060400001A16150300000A0809 0B0B0B0000020C0C0E00000208080A0000020F0F111111110000020000000301041A1819201E1F 0B090A0300000602030804050B05050D05030D03010F0400130400160500170700190700140100 1B09051101021508110E02102C2338241C340F0B261517301B213922263F171B34383D531C1E33 1113283132472122372D2B412D2B4126243A211F352321372C283F2D29421A1430281F3C221735 281B3716082225152F27152B362132442C39462B3049292A421F19492117512314764534541907 8A3D29B25C45A54C2E9D401ED16F48AC451ACD6236C6572AC55629FE8D61FF9165B64314C85620 E57337FF9453DD5F25D13B1AE84C35DC4D2FD45431C95A2FE28051E28353F39464DE744ADB6740 CA4A27D14A2AD64D2DF86F4FEE6946E8643DCB4113B62D00B33409D66038D96D47CC5B3BFF7B66 B51F11E13E37D3312FA31312A32D2DB960623C0606200C0B1106042F100E200000CBA3A13D1110 6B3336BE8A8C38120F1D0000834C517A484B270B07120000471A17895653734841461D17895D5E 2C00046E4549502C30150000977D80553C40493238110000270E121600004E3032EFCDCE563232 4C29278266631C1210150909310E122A000044000081212D7B15225400003F0000813B3D683230 3E16147C5D5B5D4342533A3D1B09090C0500231E18453E38080000524444CBBCBF38292C584C50 0B0205070103B7AEB1FFFCFFF0E4E82A1A1D5C474CB19EA2DED5D82927281312101615130B0A06 0201000C0904231E1A1B13102B211F2E2423C4BABB22191C060000241E22CCC6C8C0BCBB0A0605 0A04040C0606040000040000241E1E645E5E271E1F0600001A1112060000070000241B1C554B4C 060000080300070300080300070300080300070300080300070300070200060200070200060200 070200060200070200060200060200060200060200060200060200060200060200060200050100 050100050100050100050100050100050100050100050100050100050100050100050100050100 050100050100060200060200060200060200060200060200060200060200040000030000050100 0D0906120E0B0F0B080905020703000300000A06031D19160A06030300000F0B0815110E16120F 0E09060B060309040046433E514E474E4B4476736C43403919161147443F0302006F6E698A8984 67675F3A3A3227271D39352A6C685D59524839312650463C584E448C7F7693867E887B73695C54 6257510E05000D04004B443E4B46420601001E1B165B5853221F1A1916113D3A35322D2A27221F 040000130E0B0703020400000300000D0908120E0D010000040203050304030102030102070506 0D0B0C0E0D0B0A0809030200010000161513302F2D3433311C1B190201000100000A04040B0603 0E05000F05001305001606001705001705001B08010D000017080D23172304000E221934322B4C 0A0629101332191E3C272B48282C47393D5830344D2729402B2D422021362324392F2D431F1D33 2F2D45403E561B17320F0A28211E3D2A24462F2849241B3A221737291A373B2943452F44543C4C 2D131C553B3C8B70694E30253C1F0D6647324A240D854B35651F0684391CE28F6DFDA17CC8673D A64115C86136A53E13C55E31FC9366D06435F88954DC6731FF9C61E55D2DC1220CCB291AC93C21 E0643EF18956C1642BFFB478FFC68DE37A4AE06D41D0522CD04E2AFF8861C7481FD75A2CF27642 E0612AC84B13C44F1AD66334D9683EED7553DF573FD94335FA5752C82425A30C11C04246963D41 310000160402120904270A06350F0CBD9A982E020384454EB87B833A0D121C0000723D4378474B 260806130000340C0A8A5D5A805751350E078A62602B03032801024E2A2E311116795B6341262F 5339443019210F0000120000240709AE918D987A722B090040281E4E473F1C130E1D0000330000 690F1B9C31419A27368F212C8629316F25265D2524623B3690736F59413F3F292B0D0000060000 2A261D271D1B0800003B2B2EB2A3A62E1F26594E540903070F0A0E8E898DFFFDFFEBDFE3352528 472E32BBA8ACE8E2E4292A2C0909090A0A08080403070300130B08271F1C170D0B3A302E605856 ACA4A2040000130D0F030002AFABACA6A4A50302000501000B07060602010300000C0606342E2E 342E2E040000160D0E070000080000191011473E3F130A0B080300070300070300070300070300 070300070300070300060200060200060200060200060200060200060200060200060200060200 060200060200060200060200060200060200050100050100050100050100050100050100050100 050100050100050100050100050100050100050100050100050100060200060200060200060200 0602000602000602000602000602000300000501000A06030C08050804010501000501000B0704 0D09061F1B18110D0A0300000A0603070300060200100F0B100F0B0A0905302F2B32312D54534F 38373312110D32312D23221E0201008A898591908C6968641817132928235A574E9E9C90645D53 5E574D5C5249544A419F928C26171275666170635D514642665D580C03000E09034B4642413E39 0300001A161524201F0E0A090F0B0A1915140F0B0A100C0B120E0D0804030703020300000A0605 0F0B0A0300000300000100000100000100000100000100000C0B090B0A08010000020100030200 0A09071413111514120A09070100000C04020E04030F0601100500130600130400130500130400 1D0F0C1E0F12160A1407000C0E061D150F2B2620422F2B4E1717391A1D3C2A2B4938385430304C 4B48634B47602B27402F2A41353047423C5628223C4D4763736D89443D5C47405F2B26462E2949 3831521F16352C21412D1E3B47354F473146341D2D70565F351B1C270C054D2F24684B39654631 9A765EAB7761A5674EA66144C87C5ACE7954B65A31A544199C390FB44F25B44D24D66C44FFA67B FF9F70CC5422DB5E28C94213C42E13DC462ED34A2AEE7349D56A34CA682BF7975AF39055E17841 EE7B4CD0572CFF885FE16235D55727EB6F3BEE753EF98049E36F36FA8854E07040E8774DE8704E B12A14DF5042E84F49AE1817A82022C9585C5F1013290000140200190B081F00005E3531AB8381 2200009F6069A6697131080C1B0000734047532528140000351C173D13148757577E514E3E1511 79514F4E282719000039161A2F1015684D546D535C2B141C59424A1500041A0003140000694C48 CFB1A94220171300003D383225201C2002042C000064172194364486253073161E8C3D42511413 6034316F524C6B534F2B19152210100A00000A0300120E05150B090A000078686BA8999C2D1E25 30252B0600041510147E797DFFFCFEEDE1E52E1E213C2327CFBCC0F5EFF12F3032080808060604 0703020602000B0300160E0B110705342A286E66647C7472040000150F11241F23E5E1E28F8B8C 0C08070501000C08070C0807080403040000100A0A2F29290400000C03040600000C0203080000 291F20150C0D080300070300070300070300070300070300070300070300060200060200060200 060200060200060200060200060200060200060200060200060200060200060200060200060200 050100050100050100050100050100050100050100050100050100050100050100050100050100 050100050100050100060200060200060200060200060200060200060200060200060200040000 0501000804010804010501000703000C08050E0A0706020016120F110D0A0703000D09060A0603 0D0906080703050400100F0B0D0C082C2B27504F4B0A09050100001D1C18010000302F2BA4A39F 8887832D2C285D5C585E5D58726F66211F13423B31817A7032281F4C42396C5F594C3F39231512 7B6D6A6D625E7B726D2E24220400001B16123C3934322E2D0804030602010B0706040000030000 030000161211090504030000050100030000080403120E0D0703020905040706040403010B0A08 060503010000100F0D1A19170706040100000100000100000605030706040403010201000F0402 1005031106041106021207031106041005030E04051B10162E242D221A290300101C16300E0726 1B1537403C5F2423452120422827473B3857211C3A57516D69607B2E243F261C353D334C3C2F4B 1D132E332846403553281D3D403756352E4F352E4F362C4E24193930234137284544324C3C293D 3A2333473038391F20250A032105006346346E4F3A3A1800592D14C794799E6142813D1AC67851 8B360D9F44188D2D037E1C0099360F98300BE37750EF7B52D65D32DD6030D65329B62D0DD14A2C E3633CCD5425B24109FF9759EE8647BE5619D56B31D3642DA83403FF8755AD3300F1753FE2672E D1581FDF6E34DB6E36FFA36FEE7F51FF956ED55C3DC5432DE65E50AD221B94100CB13B3BB05052 3A00002B01021907051C0D0A1B00008E5E5C9165622B0000AD707792565E2600021A000075464C 2D030712000049302C4013168E5C5F7543445224246139396744421E00002C0C0F1600004E3338 A68F950F0000432C34351E241300001400002E110DAA8982805E551200000B08011E1A17270F0F 2800004A0911641721600F165E1117581A1B44141060413C48342D2617120800001305050F0402 130E080400000C02001E13119C8C8FBFB0B3291A2112070D050003100B0F8C878BFFFCFEEADEE2 150508452C30D4C1C5EFE9EB2F30320D0D0D0E0E0C0F0B0A0905020600000800000F05033E3432 756D6B59514F100A0C040000605B5FFFFEFF7672731915140501000804030A06050E0A09080202 0B05051610100400000900010600001208090700000F05060A0102080300070300070300070300 070300070300070300070300070300070300070300070300070300070300070300070300070300 070300070300070300070300070300070300070300060200060200060200060200060200060200 060200060200060200060200060200060200060200060200060200060200070300070300070300 0703000703000703000703000703000602000400000602000804010703000703000D090616120F 16120F0300000A06030A06030703000F0B08120E0B1C181505040001000017161201000043423E 31302C01000002010001000014130F71706C8A898544433F7B7A764C4B471817123A372E1D190E 0B04006C655B2920173F352C40332D776A640A0000403531857A764F464148403D211916040000 100D084B4746302C2B0300000C0807120E0D0300000905040501000D0908030000060201030000 050100100C0B0A06050A06050100000100000B0A080B0A0801000001000012110F0A0907060503 06050305040203020001000001000003020013040114050213050412070511070810070A0E070E 0D0711110D1B141021373449302C45201B390F0A2A272143221C3E2C284B2925482C26483F3859 231A395F52707A6B883525423525405646613D2A483727444132512516352517383D2F503D3453 3A315029203F2F24443326444637543C2C473522382A132539222C3A20233317134E3226361907 4729118E6E55603C22593014734120A268439E5930621500BA673DA64E26963C17B45632D3714E F38C6BFF9E7B9A2601AF350ED75D36C24A27B53F19E26C3EB8430ECC581DF98749FD8D4DCF6122 EA7E40C65C20BE5119D96A32F27F46FE884BD85E1FE36D2FEC854BED8C55FB9564FD9065FF8E69 C64D30E66852CC4E3F8C11097D0D099C3D3B7D31313300002705041604041C0706250000AE7B78 744440461413B0737A7E474D1A00001F030272494F280106210909341A192800009E676D773E45 602C30542C2C62403E1800002F11132A10131A01058D767C2E191E1904093D272A1A01041E0201 1D00006F4E49AE8B85250C050300000B0C0715050527070A39060B3500004E10157A4243310502 3C1D18402D261309000D06000D08041008061008060904000D0900070000291E1C5A4A4DE4D5D8 2C1D241C1117070105090408807B7FFFFDFFCDC1C50B000040272BB3A0A4E7E1E32F3032141414 15151314100F0E0A070B03000E0603110705473D3B8E86845B5351100A0C0500015E595DDAD6D7 524E4F201C1B0400000501000400000B05050A04040B05050800000B0203110708080000140A0B 0A00010A0001080000080300080300080300080300080300080300080300080300080300080300 080300080300080300080300080300080300080300080300080300080300080300080300080300 080300070200070200070200070200070200070200070200070200070200070200070200070200 070200070200070200070200080300080300080300080300080300080300080300080300080300 0601000702000803000702000702000E090617120F1D18150400000904010904010500000A0502 090401110D0A0C0B0701000011100C1514104B4A460B0A060100001B1A164E4D49605F5B585753 4B4A4684837F4847434B4A464B4A4519160D0A06000E0700686157372E27362D26463B353D322C 433834080000584D4B382E2C322A271E1613130E0A0F0A060905043935341B17160602010F0B0A 0703020F0B0A1713122723220A06050C0807090504030000060201030000030000030200010000 0100000807050100000100000504020302000E0D0B050402010000010000040301090806050402 18050117050115050512060812070D1009110F0B190F0C1D0D0B2118183031314D312E4B282343 1F1A3A262141201A3C2824472E2A4D302A4C443A5C372C4C60517083708E45304F513A575A4360 220A2A2D18373D2A4A200F2F3425464032533E33533328461C113131264433264446375434243F 311F356651622A151E341B1E583F3A7F635746291740220A76583EA18168967357885D3B8C5A35 A3683E98552A964D22E6996FA859328A3813893312B75A39F99676AE4525A13310C0522DE9835B C76236C55928E16F39DE672DC85013E77133F48243C85C1EB54D10E88146CE672CDD7133D96729 CC5415D66426FFB77CFFBA85DE7E4CFD9369D5633FCD553AE46B56A935268F241A690F07792E29 571D1B360D0B1F01011300001A00003E0C0BB77D7B592824622F2CB073786935391500001F0705 7A565A2804081B0605270D0E29000290545E6F313C7E474D3E16176C4D4B160000240709493033 1500024B363B7560651200022410122910131F03022708064E2D289F7C764E352E0400000E0E0C 0F03031C03062902052F02054B1F205C34341D00003320191D140B030000100F0A0D0906070101 1109070400000F0B021006040E0301342427F4E5E852434A0F040A0D070B050004544F53FFFDFF AEA2A60F0002280F138F7C80F5EFF13D3E401D1D1D1515130F0B0A0B07040C0401120A07120806 1A100E837B796058560500011A14165B565AD4D0D12D29282521200602010C0807070101080202 0802020802020600001108091006070700000C02030E04050D03040D03040A0200080300080300 080300080300080300080300080300090401090401090401090401090401090401090401090401 090401090401090401090401090401090401090401090401080300080300080300080300080300 080300080300080300080300080300080300080300080300080300080300080300090401090401 0904010904010904010904010904010904010B0603080300070200080300060100040000070200 0D0805110C090400000904010B06030601000904010400000400000A0603060501010000363531 32312D0201000100002B2A2614130F21201C51504C51504C3534306D6C6834332F0502001C180F 18140940392F4F483E534A432B221B5249421C130C5247431108031A100E251D1A19110E0D0502 130E0A100B08040000110D0C1C18170300000E0A09110D0C0300005652513A36350A0605080403 0C08070300000300000300000804030D0C0A0403010100000201000C0B090A0907010000010000 0403010706040706040302000201000504020807051B0601190602170505130409110710110B19 120F221111291314302728471F203F1E1D3D2C28493A355530294A302B4B201F3F2E2D4F2D2749 3A33544A3C5D5B4A6A877291614A67806785674E6C2B12302810303926463625454839584A3B5A 4538562F223E211432302341392A493728452F1F3A332139372235220C18553C40533A362A0E03 3A1D0B72543C94765C82674C8C6E529E7A588B5F3AA77248C18759A5663AD49468612000712D08 87411F6C2101681800822C0B9C421FAF5530D58256DE8859CC6A39E77946CD5520E0632BE76C33 FC884DCE642AD06C31F09255EB8D50C15D21DC7032DA6728D86C2EF09E66F4A773D67B4CE37E54 B84725E67056D7644FAF45377921155C160E6B342F4E26242809071A0202240F0E1A00005F2927 A86B684A1511723F3CB4777C5422251800001704006C4C4F2D0D120E00002D14174D1B267F414E 763442975B672800037C5E5E2408071200003620224430312612148C797B2411130E00001F0609 12000022040226050067443E6F534F0600001514121206061200001A00002D0D0E3C1E1E190000 1809022C231C0B08000607000E0D080300000A01020F06070D0802050100150B09080000352528 D0C1C46B5C630700020D070B0601053A3539FDF7F9B6AAAE1101041C0307968387FCF6F8414244 1C1C1C11110F0A06050703000901000D05020E04021006048B8381453D3B050001322C2EABA6AA D4D0D1120C0C25201D040000110C090C07040803000B03010C04020800000F07050B0100070000 0800000C00000C00000D03020A0200080300080300080300080300080300080300080300090401 090401090401090401090401090401090401090401090401090401090401090401090401090401 090401090401080300080300080300080300080300080300080300080300080300080300080300 080300080300080300080300080300090401090401090401090401090401090401090401090401 0C07040803000601000904010A0502070200050000070200070200040000080300080300050000 0C07040601000500000400000300000300003A36331814110C0805100C09211D1A16120F4E4A47 15110E110D0A6E6A673B37340300000A07022C27218A867D403C330A06006C655D29221A443D37 19120C1F15133F37340600000F0704140C0A0B0603040000040000211D1C030000070302040000 0F0B0A0B07060300005A56554642410400000300000D09080501000501000B0706171312010000 1A19170E0D0B0100000302000605030100000201000100000B0A081312100A0907010000010000 0A09071E06021B060317040613040B120612120B1D1410291414302021401010321E1D3F383759 262042534C6D534C6B211C3A1E1D3D2D2E4D2522412C25444E415F5542608C75927C61806B4E6D 4F32503217362C1331432E4D5E4B6B6251715E4F6C54456233264030233F3124404334532B1C39 32223D37283F2B182C3D2935654E54684F4B553A2F8D725F6E4F3A2C1100432910321700603F1E 764F289F7044784516946030BC8658966135461100A56D48B87E59E5A683AB6946AC6740934B23 B87548E9A16FFFBD8DB04A19C34D1BFF9460FD814DD35E28F58C55DE7F47AF561ECE753BEC8F56 DD793EBF5217D9753AC57A43D28C59F39F71CB6A40B04420E07155B04630A245344E0400541E14 744D48573B381100001C07063D25251E0000783E3D985856400B07764340B87D814615181D0503 0E00004225294124281202022E151863313C8A4A5A934E60925564250002725655280B0D110000 0F0000655152170406816E704A37391D0B0B1A0504120000270907160000512E2A9377741D1111 0F09090800001707081903051A05042C181710010029221A2B281F0101000506000B0A06070200 1C1213070000120D070A06000700001D121013030698898C5B4C53160B110A0408070206413C40 F3EDEFD4C8CC0B000022090DB8A5A9EBE5E73132341010100B0B090B07060D09060E06030E0603 0700004F4543C9C1BF221A180A0406413B3DFFFDFF938F900400001E19160400000A0502080300 0500000C04021008060C04020C04020B01001006050E02020D01010A00000D03020A0200080300 080300080300080300080300080300080300090401090401090401090401090401090401090401 090401090401090401090401090401090401090401090401090401080300080300080300080300 080300080300080300080300080300080300080300080300080300080300080300080300090401 0904010904010904010904010904010904010904010B06030702000601000C07040F0A070D0805 0904010803000F0A070400000C07040500000400000C07040904010904010D08050300001C1815 2723200D09060D09061814110300000E0A0729252225211E3D393626221F0F0B0803000025221D 7D7872040000080400100C033831293F3830150E08201B15090100211916060000130B080E0906 0E09060904010702000300000400000905040B0706030000030000130F0E1B1716555150070302 030000100C0B060201030000090504191514010000403F3D3B3A380A09070403010A09070C0B09 22211F0706040807050504020100000201000807050908061A05001D08052613152B1A221E101F 0D0417150F292A25452E2A4B2420430A0629312B4D37304F261D3A6B627D37314D2B2C4A191D3A 30304C241E3A473855533F5BAB90AF5B3C5B5736554423402C0D2C2F15324B34515A47655F4F6C 695A776A5C754C3E5732243E31223F37284735264331233D33243B3E2B3F5C4854654E54523A38 7D62577358456F503B51361B2D13004E33183C1B003A140080552A603403865826D9AD7C815928 B38D60E1BA91F3CCA3A67C54BC8F6687562D9C693C7C46188C4E1DAF6131C16232E17342ED7747 CF5929DD6D3BC15D2BC96F3DFFB987D68550FFAB78FA9F6ACC6932D67842BF7745B47242FFB98C B65930B54E2BAF4829A5422B7522104305002100006C504D422E2D1400011C0706593D3C270000 A167655818163500008E5B58A0686B3F11130E00001709063E242741262B0A0000210B0E6B3945 7030418E495B9B5E6D260003684B4D2D10121A02021701032612134836365242426A5A5A241212 0F0000130000260A071800002200008F73704333340800001406061404050F000023110F130502 130A05120D070F0C050B08030A07020C07040F05041203060F0303140D070400001309070D0200 312124A7989B52434A1B10160E080C0300027C777BFFFAFCD2C6CA17070A30171BC8B5B9E4DEE0 3031331E1E1E000000151110050100130B080F07040700009D9391857D7B0B0301060002231D1F EDE8EC4945460601000702000904000A05010D05020C04010D03010C02000C02000C02000D0200 0D02000D02000D02000D02000C02000A02000A02000A02000A02000A02000A02000A02000A0200 0A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A0200 0A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000B03010B0301 0B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B0301 0B03010A02000A02000A02000A02000A02000A02000A02000A02000A0200070000060000080000 0D05030F07050C04020601000601000803000C07040E09060E09060C07040803000601000B0603 201B1817120F040000120D0A060100140F0C342F2B2F28222E271F040000040000130E08413C36 040000120F0A100B070C07030A05020702000A05020702000700000803000300004C4847060201 0501000C08070400000C08070602014D49480C08070D0908100C0B030000060201030000040000 0605030605033534322E2D2B050402010000070604252422100F0D0F0E0C3B3A38010000343331 131210010000200D091400001502042A19213E2E3B3A2D41281B35190E2C2016382F25474A4062 180F2E2F25403228414A4058615C731A1C3520243F35324D2C233E43334E60476494759454314F 411C3B3E1A36310F2A371935573D5A6D567266536F5C4C674E3F5635263D21112B251731392A47 4B3C59544562574962746278806E7C301B223D25234E332A482D1C65463162462E492F1842270C 2E0D00401D00AA8153BD9361A9814D96713CA78653B79967A88D60A2875A6D502487683A765426 967041855628773F109C5625883503B45221B54B1BB24818FFA777D37748C06C3EE7996BEAA071 DC8E5EC57343FFB987D3804E9D592AFBB88BC87B4FCA7348D6764EC36543963F248A412E3C0800 2E09036C54542815171D090A29111161423F310502A46A694509083F0C09875554A97277390C0F 1402001207052D14184B32360F01011905076B3B477D3F4E7D3A4BA96C7B2F060C5E4042321517 1500001500011D0B0B3828284D3D3D5242422516131906021100001F06021A0000180000684C4B 4430310B000019090A1606070C00001A0C0B0B02000C0500110C060F0A040D08040E0603100605 1305051502041101020B04000905000C020008000038282BD3C4C7786970150A10070105080307 888387FFFDFFF1E5E929191C2C1317A59296FEF8FA3F4042232323020200191514030000100805 1008050E04029B918F655D5B110907040000241E20E2DDE13935360702000803000904000A0501 0D05020C04010D03010C02000C02000C02000D02000D02000D02000D02000D02000D02000B0100 0A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A0200 0A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A0200 0A02000A02000A02000A02000A02000B03010B03010B03010B03010B03010B03010B03010B0301 0B03010B03010B03010B03010B03010B03010B03010B03010A02000A02000A02000A02000A0200 0A02000A02000A02000C04020901000800000B03010F07051109070E06040B0301070200090401 0B06030D08050D08050B06030904010702000A05020400000500001813100400001F1A171A1512 040000665F59453E3604000015100A0702004E4B440401004D4A4524211C16130E040000080300 040000040000110907080300140E0E4E4A490804030501000C08070400000A06050300004C4847 110D0C0B07060703020300000300000501000A060505040204030112110F1F1E1C0A0907010000 0403010201000100000403014746443A39370403011A19170C0B091D0B091705031303041D0C12 2D1B273926393A283E382640321F3B1F0C283B2B462616303729403D3044372A3C6962741D1E33 25253D36314830243C3C253F6A4C66845D7A5A2F4B471A374D203D451A36451E3B63425D765C77 68516D513D563C293F3E2C423D2D4741314C4A3B585748655C4F6B5D4F6860516650404D7A676D 624D4A8469607156454D2E19795D45957B6470543C4322013E1B00674112BB935FA37E4765450C 866832846B3566501F755F2E604A19614919997F4EFADAA98E62337B4516DD9D6D8A410E833000 D87E4AE98D5CAD5223B561359D4E259950279F5A31AC673DE0996DF6AC7FBC7346AA673CE6A378 F4A77BF7A478C77045D58059BE725265240E2E000043221D70575A150005250F123216155F3C38 4518139D65642E00004F1F1D825454AE777C380B0E1A08061106041D040851383C120606110000 5F343D874D5B602231A66E79481F2756373C3D20241300001701031503032314113E302D2E201D 20130D1F100B0E00001702001D0501120000391F1E3B25270F00001C0A0A1707070C0000140907 0900000C0401110906110705100604110604140605170505150102100000090200130F060B0100 0800003D2D30EADBDE97888F0700020F090D0C070B6C676BFFFAFCFBEFF33E2E31250C10A9969A E5DFE12425271414140909072A26250B07040E06030D05020F0503786E6C453D3B0A0200110B0D 938D8FFFFDFF322E2F0803000A02000B03000C04010C04010C04010D03010C02000D02000D0200 0D02000D02000F01000F01000F01000D02000B01000A02000A02000A02000A02000A02000A0200 0A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A0200 0A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000A02000B0301 0B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B0301 0B03010B03010A02000A02000A02000A02000A02000A02000A02000A02000C04020A0200090100 0B03010F07051008060E06040B03010904010904010A05020B06030B06030A0502090401090401 16110E0702000400001E19160D08050702000D080536312D6F6862211A140C07010400000C0904 2926213936314A49440706020D0C080300000602002B25250903030F06070400001A14143F3B3A 0602010300000B0706040000090504030000262221040000080403090504030000070302070302 030000060503070604010000100F0D0A09070100000D0C0A010000060503040301020100464543 3F3E3C0100001413111507061E100F20101119060C17010D281020432A3D593D537E627951384E 2B1329483346311E314938487F717E867B8B433E52201B32372B433420393719336E476290627F 6E39576A33526A33505A25434F213D5F375268465F593B55492F48624C6173607477657D5E4E68 42344E3324412C1F3B26193333253C594858513D46846F6E7D6259967B6A664A348468507F654E 6A4E3694765455320A5933027E5720B08C5278551B694A116348113E27006D56248E7745755B2A 997B49CDA977AC7E4D7A4616B37A45B77842DA955CC87F48A65B24AE6230C1774A8E471D5E1A00 93522CA86842B1734A6C2F03B97A4EB6724BBA724AA85E31DC8E5EC77949AD6336C2805D6D351C 2E0200633F3F6C4F5419000726090E3917184E272061342E8653522300005D31308458599E696F 43161B1C08091106041A0004472E321408080F0000451D2587525C4B131E8D5A63694048533338 46272C1300001D07091402001102002C1E1B130802160B051C0F090D00001504001E0B05130000 230B092914130E00001907071608070E03011208060B0300110906110705110604130504150505 1606061705051501021001000E0700110D04100604080000433336CEBFC2A3949B070002161014 0300023C373BF4EEF0F5E9ED564649291014D8C5C9DCD6D81415170707070A0A08312D2C0D0906 0C04010D05020700003D3331322A280600001A1416C8C2C4E6E1E5130F100B03010B03000C0401 0C04010C04010C04010D03010D03010E03010E03010E03010E03011002011002011002010E0301 0C02010B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B0301 0B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B0301 0B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B0301 0B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B03010B0301 0B03010B03010B03010B03010901000800000800000901000C04020D05030B03010901000C0402 0904010904010904010904010904010904010A05021E19160D08050F0A07090401130E0B040000 25201D5F5A5648403D060000100B050400000B080311100B64635E11100B0100000B0A060A0603 0C0805655F5F0B05050600000B02030D07071F1B1A0300000300000A0605030000080403050100 110D0C0400000A06050D09080602010A06050804030300000807050B0A08010000080705030200 0100001716141D1C1A0B0A080100000D0C0A0302003332302F2E2C090806110907180E0D1F1013 210E12290F183719254321314924354C27388C6A7A8262715C404E361E2B4E3A4597888F483B45 6E62761C0E253C293F44283F471F39774560B277958342608643627E3B5A6B2C4B6126445F2D4A 562A454B233E4A28413E253A4B384C4F3D553D2D4732243E3A2B484336544336504A3C53423443 3C2B332F1B1A6B53498C716082665062462E260E00351B026B4D2B7D5A324B25007A5119936B30 744E1042200088682FA0814BCCAC79CDA9797A542370461470421095612F915C288D591F956223 B58241B47F3DA56A2EAD7039BE7E4EAE6D435A19007739149D663F8A572C5829009D683CB7734E 691D00A2582BBF7544AE6834F1B181955B357C48305B2F26865F6258343E26020E2601094B2324 41160F784C436333311F0000653E3F7E55597D4A51592C3319050615070720030830151A110604 1608072905098051574A191F6E3F45784F574E2931402025140000230B0B1A06050B00001E110B 1005000F0600140A010F05001407001809021401001D0A041C09050E0000140502130804100702 1009030C0703140C091106041305041405021506031607041607041304010D0200110A02040000 140A081207054030338A7B7E998A9110050B0C060A030002575256F2ECEEFFFAFE6E5E612D1418 D5C2C6FEF8FA27282A0B0B0B0606042B27260602000A0200120A070B0100514745453D3B060000 0F090B8C8688A29DA10300000D05020D06000C05000C05000D04000D04000E03000E03000E0300 0E03001002001002001002001002001002000E03010C02010C02010C02010C02010C02010C0201 0C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010C0201 0C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010C0201 0C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010C0201 0C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010A00000A0000 0A00000B01000C02010D03020B01000901000C04020B03010A02000A02000A02000A02000B0301 0C0402140C0A060000170F0D0600000700002C242250484618100D392F2D0F0802070200120D09 03000043423D3A39350E0F0A1718130F100B0F0E0C2E2A294D4747060000060000110809060000 0400000300000501000B07060300000804030804031F1B1A1612110B0706060201030000040000 0B07060501000807050403010D0C0A0100000100000A0907100F0D2C2B290504020100000B0A08 0E0D0B0100003635331E1D1B110D0E150C0D1A0E102510152E131836151C3F1720431822613640 855A64D3ABB4D5B4BDCCB1B83A232939262A4A3A447E6D7F2C162D462A415C364F65334E8B4F6B CB86A5914665974868914464863B5A7F3A59783C58652E4B57274159314B42263C3E293C342137 2C1A3431213C3E2F4C3A2D4B2D203C36283F2B1D2E3928303925243B221B987D6C5F432D462A12 331D05371F05422503AB8A5FA47C49C49A609F7237714508BE9458B1894E956C36C59A67CE9E6E 875324854D1E935929C087528B541C805010B88D48B69047A27C33A179339565279B6330E9AC80 BB7B55400400935F38A0754A6E4C1CB5895AD48E6C8D3A18C3764ACC8652B3763DAB743E825128 75472D8A5E55966C703E14222C00112C000865373944150B8054494115122100006B494A633F43 56242D71464F1D070A16060723060B1F04090E03011D0F0C1A000073494B5124275B31356F464E 421D25300D13160000220809200C0B0B0000150A04160D060E05000F0600130A01130900110400 130400190A03190703130400100501110A040F0A040B08010A0501100805120705130502150301 1604021506031508021106000E0500120E050400001208061E13112A1A1D46373A796A71070002 0A0408171216B0ABAFF7F1F3FFFBFF7B6B6E230A0E9E8B8FEAE4E618191B0404040606042E2A29 0A06030B03000F0704160C0A9288864F4745060000191315958F91ACA7AB0500010E06030E0701 0D06000C05000D04000D04000E03000F04000F04000F0400110300110300110300110300110300 1103000E02020D03020D03020D03020D03020D03020D03020D03020D03020D03020D03020D0302 0D03020D03020D03020D03020D03020D03020D03020D03020D03020D03020D03020D03020D0302 0D03020D03020D03020D03020D03020D03020D03020C02010C02010C02010C02010C02010C0201 0C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010D03020D03020D0302 0D03020D03020D03020D03020D03020C02010D03020D03020E04030E04030E04030D03020C0201 0B03010B03010A02000A02000A02000A02000B03010B03010600000C04020600000B03010F0705 3F37352B2321060000403634150E080700000401001A17125E5D5800010048494423241F000100 11100E5857550D07070C06060700000B02031D17170300000905040905040C0807040000060201 080403151110130F0E0300000501000703020300000B07060602010504020100000B0A08010000 04030112110F01000017161406050331302E0100000F0E0C131210010000201F1D19171A191516 2014162814162C0D12320B1046191E5D2C326A373EBC8B91FFE3E8D7B0B5A88A8C482F32301C1D 2B181E755E705739515029446A3C587C415FA45F7ED384A4A04B6CAA5073AD5678A550719A4B6B 954E6C874865743C576A3C564D2D423F2A3D332036301E363929444233503B2E4C2E213D1B0D26 2A1C2D3A29314D3938563D364F3423947862533920432F162E19004026038C6B40F5CD99B3864B AB7A3F6A3800A9773C9E6B32A36E3AE3AB7AD09165874417894013AF6737D2915BB47C3FB18440 CAA95CEDD482C0AA57967B2E95702CAA7941F5BD8EF5B7908349239E6F45815C2F482E00D2AC7B F1A887A54F2EBD704496531EA971365827003D1100AD81647D514881525836031432001234000C 6F3D3E4C1C10794D402A02002804066E4E4F3A171B370812855A64261013150204210208210409 0E03011B100C1800006038394A2324522B2C5E353D4018212400061C00021B0102210C0B100100 130802160D040E07000D0600150C031108010E0300140903130600160901170D040E05000D0900 110E050808000906000C07011308041305021402001203001306001207011009010D0900100D04 0C08000B01002E232117070A37282B7162690700020F090D282327CDC8CCEAE4E6DCD0D4837376 230A0EAC999DC0BABC0000020000000A0A08383433130F0C0C0401080000241A188B817F302826 0600003D3739E2DCDE9590940400000F07040F06010E05000D04000C03000D04000E03000F0400 0F04000F04001103001103001103001103001203001103000E02020D03020D03020D03020D0302 0D03020D03020D03020D03020D03020D03020D03020D03020D03020D03020D03020D03020D0302 0D03020D03020D03020D03020D03020D03020D03020D03020D03020D03020D03020D03020D0302 0D03020C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010C02010C0201 0C02010C02010C02010C02010D03020D03020D03020D03020D03020D03020D03020D03020C0201 0D03020E04030E04030E04030D03020D03020D03020A02000A02000A02000A02000A02000A0200 0A02000A020006000018100E0600000A02001F17151D1513060000170F0D463C3A0600000F0704 030000423F3A31302B11120D5A5C57050702000100232220504F4D040000140E100700000E0508 443E3E0400000E0A090602010A0605050100050100060201110D0C120E0D030000090504110D0C 0300000804030400000201000A09070706040100000908060908060100000C0B09070604282725 4D4C4A010000100F0D09080601000026262E211B25251821381E27461E274C1B215B23266E3231 8B504CE5ABA7FFF1ECFFE9E57E5F5C412728402B3037232E684F647E5E765227426E395583435E B76B87D27C99B0516FBB5B77C66682B95C7BA34E6D9F53719B5673874865703E597B5A6F654E60 4D374C35213A261631251633291C382C1F39382C422719285D4E5383716D796355816852A88F71 886F507D6A4C836F4E280F0089693A9A733C895F237F511398682A7F4E138F5D2297622CBB824D B77845C57F4CD08450CF844DCF8D519D6623ECC079E0BF72CCB160CCB565DCC277B08F4CAE814A BD8B5A854E25AD785093663C8A66366D521D66400F9955309F512D9F582CA769386D3A0391632F AE845A6F462A4F231862313439051137010F37020A6936355020167044392300002C0A0B705254 1700002600048E666F2F191C1300021D0005270D10110300190C061900004B29283C1A184B2928 512E323D1D221C00022205071600001E0A091203001508020F05000D04000D0400150C03110600 110600190E080D0200130802170E070B04000C08001310070C09000B08010F0802140905130502 1203001003001005001108011009010E0A0109050018110B0800004234331608085546498A7B80 0F040A0E050A1E181CA49EA2D3CACF93878B8F7E84321D22FCE9EDCFC9CB0E0E0E0907080F0E0C 373330130E0B0C0402060000594F4E645A59221A18140B0C6E686AFFFDFF3D373B040000100805 1007020E05000D04000C03000D04000E03000F04000F04000F04000F04000F0400110300110300 1103001103020D03010D03020D03020D03020D03020D03020D03020D03020D03020D03020D0302 0D03020D03020D03020D03020D03010D03010D03010D03010D03010D03010D03010D03010D0301 0D03010D03020D03020D03020D03020D03020D03020D03020C02030B02030C02030B03010C0203 0B03010C02010C02010C02010C02010C02010C02010C02010C02000C02010C02010D03020D0302 0D03020D03020D03020D03020D03020D03020A00000B01000C02010C02010B01000A00000A0000 0B01000A00000A02000B01000B03010C02010A02000B01000901000E04030600000E0403060000 160C0B0600000E04030600004C4442070000120D0A110E094C4B470102004345403F413C000100 0E100B3F3F3D1F1E1C0E0A0B120C0E060000241B1E605A5A0A04040E0808030000060201060201 06020105010034302F2B27260400000703020D09080400000903030C0606030000201C190D0908 0B07040C08050100000F0B08181713100C090300004F4B48312D2A04000008040108040118192E 29243A432D4439132A4F182B6A28327A2E2EB06359EDA491FFE0C8FFDCC49C715E8968614D3438 3E293837243A4129419A7C946F4761824C6489455CBB697FD27588CC667BDC7286DB7489D06E85 BC627BA959749B55718C4D6C7A48636E4D62543B4E442C423C263D3826403E30493C30482C2036 3B30407D727A968B878F81748070577966458673498673484A370F654F266A4F22A58753B18E54 AE8A4C6A47056C49078C6929BC965781591BF2C486EAB474E1A463DD9A56C5823CD39950B07C31 F5C57DD5AB63D0A862BC9753D8B274D1A872B68A59AF835488592D9A6B41603407784D20734B1A 3D1100632D01652C01A67044A8754A9E6F459E724BBF9474592F16A97E6D6034293606023A0807 3807034E1D18713F385627211B00004A28276446462002042303085D3E433721231602031B0507 1B05071602011A0703250C082509062D110D422924452D2B2A15141602011805011E0C081B0905 150601150601150802150802150802150802150802150802150802150802120701110803110803 100903100903100903100903110803100702110602110602110602100702100702100702100702 140B06080000190B0A2C1E1D0A000087787BAD9EA110040813070B090001665960E6D9E084757C B1A2A9503F47B1A2A7FFF8F9272121040000040000393431140C0A0800000700008D84855C5354 06000019101340373ACCC3C8281F240600000E04030E04020E04020E04020E04020E04020E0402 0E04020E04020E04020E04020E04020F04020F04020F04020E04020E04020D05020D05020D0502 0D05020D05020D05020D05020D05020D05020D05020D05020D05020D05020D05020E05000D0400 1006000800000B0100180F080E0500070000160D080A01000F05030C02000D0301150D0A130B08 09010007000011080B0B05070600000E08080B0205040000140B0C0D04050700000C04020D0502 0901000A02000E07010D05020900000C02000D02000D02000D02000D02000D02000D02000D0200 0D02000D02000D02000D02000D02000D02000D02000D02000D01010C02010D01010C02010D0101 0C02010D01010C02010C00000C02010E02020D03020D01010C02010F03031107064A4542040000 0703022B2A263D3D3B000100696B68888D89545955000100454744040402010000181413322E2D 1B1515463D3E12090A060000130D0D130F0E0300000100000A09073F3E3C4B4746030000130D0D 0B05050600000A00010800001D151335302C4E494604000006010015120D0400000F0C0715100C 070200120D092F2A262F282210090306000018152A291D332C10264F22366A2C3B72272CBC6762 BB6556FFD2B9FFE4C5AF785A683B26704D4771565D2A14292F1B36351D378868808258707D465B 9D5569C16D7DDB7B89CC6371D86C7BDE7383D87385C06479A8556F9A516E9354718B59746A475B 3E2538331C304832494F3D554C3E5750445A564A5E7A6F7D81787D6C635C6F6353897B60998B66 A395689A895B4B360B634B1FB59969FFEAB39E7C3F8562228A6926AD8C49AB8C49C9A865A27F3D D4AB69C69550CB924BDB9B51B6772AC99041CD984AD4A055B4823BA67533986A2C91622CCEA06E B78B5A926637BE9265AF83568354267F5022A878486E400F542A005028007F592A704B1F704A23 A4805C8A6749745237A9856F431E0C482313391105370C03572C236D41383B130B280501442523 4D2F2F1700001A00014B32353620221A06071B07081B07061803021B0603220A061D0600230C04 36221B36251E1F100B1102001405001A0B06180904150601170803160702160702160702160702 160702160702160702150802120703110803110803110803110803110803110803110803100702 1007021007021007021007021007021007021007021406031406031507061D0F0E0A0000534545 BCADB026171A0E00041304097D6E75E7D8DF867680D9C9D312020C7A6D74D4CACB170F0D0D0503 0901002E2624120A081108090B0203958C8F5950530D04070E0508483F44EFE6EB1A1116191013 0E04030E04020E04020E04020E04020E04020E04020E04020E04020E04020E04020E04020E0402 0E04020E04020E04020D05020D05020D05020D05020D05020D05020D05020D05020D05020D0502 0D05020D05020D05020D05020D05020D06000D04000F05000B01000D03001209000D0400080000 0D04000D04001007020B0100150B09130907211916170D0C0D04050600000A0408050001120C0E 150F110701010701010400000B03010F07050F07040B03000B04000E07010E07010A03000D0200 0D02000D02000D02000D02000D02000D02000D02000D02000D02000D02000D02000D02000D0200 0D02000D02000D01010D01010D01010D01010D01010D01010D01010D01010B00000D01010F0303 0F03030E02020D01010F03030F05044B454505010008040308070519191710120F9C9E9B878C88 3136321116123335320000001D1C1A5756542B27262B25253E3435140A0B060000161010171111 09050408070511100E61605E4F4E4C0300000B05050A04040600000D03041208091C14123E3935 4A423F2924200904000A05000904000C0701100B0706010011090627201A271E190F0601070000 281B24412E343C191F5B2A2D7837359F524AAF5C4EFFAB97FFD9C3E7A38C783F2E62332B4A2326 72525F4D3148391F3C3D213A76536B95687F763D50A96073BE6A79D97987CB6270FB919FED8492 D67483C2697BB6677DAB657F9B5B7685506A68475A50374A422D40402D434839505B4D665B4F67 463D503028354E454A564C4A655C4D6F634B71644292835CAC9B6F8770445C4112644411AB8850 9F7B3DCAA561AB8642A7823EB28F4B997430916A27A17632A5732ECB904AF5B369D99749E0A353 FCC372E7AF629F691F754000C69553C9965DCF9D689768346535045727006A3A0AF4C493B58554 713F0CAD824FB0925C7E6731A9945F3622004C370CA9966E2511003421016A553AAD9780957C68 2E13001F0200523525A6867735150A2708033718163416161E0201240A0B3B23232F191B130000 1C08091C0A081804031906021D080317030019050029150E26150E170803100100140500180904 160702160702190A05160702160702160702160702160702160702160702150802120703110803 110803110803110803110803110803110803100702100702100702100702100702100702100702 1007020F01001C0E0B1204011002000A0000211312CCBEBE4435380A0000332429E6D7DEF1E2E9 786872E1D1DB0E0008ADA0A7AAA0A10600000E060409010018100E0B0301160D0E090001736A6B 362D2E0600000A0104948B8EF2E9EC0800040600000E04030E04020E04020E04020E04020E0402 0E04020E04020E04020E04020E04020E04020E04020E04020E04020E04020D05020D05020D0502 0D05020D05020D05020D05020D05020D05020D05020D05020D05020D05020D05020D05020D0600 0D04000B02000F06001007000D0400120902130A050900000D04000C03000C0200170D0B0B0100 2319182014140A000111080B1A11140700010D04071910110C03040A01020D05030F0705110906 1008050C04010C05000E07010E07010C05000D02000D02000D02000D02000D02000D02000D0200 0D02000D02000D02000D02000D02000D02000D02000D02000D02000D01010D01010D01010D0101 0D01010D01010D01010D01010A00000D01011004041004040F03030E02020E02020D03022D2425 0300000B07060605030000004E504DACAEAB5E605D0B0D0A1517141919170000005E5D5B736F6E 150F0F292323261C1D0C02030600000F09090F09090A06050B0A080D0C0A70706E4A4947010000 0300000701010700000800001007080C070434302D302B284844410D0906030000110D0A030000 0905020502000B060317120E19110E0C0401060000250C083619134E261C541F11803D2AB86C55 D98972FFE9D4E79B8B924E43753B39663539471F2A4B283C5F3F573C1E384C2C44643E55916276 763B4DA8606EBF6B78D27580DB7580FA929DE57F8AC86A78B96272B16478A460758C4E67703F55 5F4052523B4B4431443A283E46384F695D756F657D534B60403847423B43332B293B3328443925 41361A63553285734BB79F738062306E4B156039009B7232EBC37EA27732845C16C49C57451D00 5C3100AA7A38B8813EAD6E29B9752CDB9649FFCE7CD89B48E7AA5A975E11D39A53D6A15FD39F63 94612886531E6C3A0795612F885623834F1DB5824DA26F3AAB804BF1D69FC0AF7964531F8D7D4A CDBF9267582F71613D45351439280C624E35200A002D14006A4F3C4629175E3E2F4B2B1E2A0B06 2B0C0A220402250908260C0B2611102915161503031A08081D0B091907031906001C0903160300 150100200D061C0B04140500120300160702170803150601160702190A05170803170803170803 170803170803170803170803160903130804120904120904120904120904120904120904120904 1108031108031108031108031108031108031108031207030D00001A0C09120401110300130504 120403C1B3B35143430E0002302126FFF3FABDAEB5594953E6D6E04A3A44D6C9D0B6ACAD070000 0E06040A02000C0402080000170E0F070000463D3E281F200800021A1114ECE3E6B9B0B30F060B 0600000F05040F05030F05030F05030F05030F05030F05030F05030F05030F05030F05030F0503 0F05030F05030F05030F05030F05030E06030E06030E06030E06030E06030E06030E06030E0603 0E06030E06030E06030E06030E06030E06030E07010D04000900001108011209020B0200191009 2118131007021108030A0100190F0D140A080A0000170B0B251919080000170D0E22191C070000 0900011E151612090A0D0503170F0D120A071109061008050D05020C05000D06000D06000C0500 0E03010E03010E03010E03010E03010E03010E03010E03010E03010E03010E03010E03010E0301 0E03010E03010E03010E02020E02020E02020E02020E02020E02020E02020E02020A00000D0101 1004041105051004040E02020D01010C02010D040507010108040314100F0100009292907E7E7C 2A2C29000200020401050503070604A29E9D454140040000150C0D1105070800000700000A0102 0600000804030A09070505036262604848461B1A180D0C0A0602010A0605050000060000030000 1E1A171814113D39361E1A170300000D09060501000501000602000903030C06060E05060B0203 09000136110132090053240A571E00894522BA704DFFE1C3F6AA93A15B51743435672F3C4C1D31 5C324A37112A3E1A3439172F512E44552E41804F62884E5DAB6570CC7B84D27780ED8E94DA7980 DA7B81D57B85C67480B068769A5B6C90576A875A6E795D6C503E4C3E2D3F4536494F43595E546C 7169817A758B7C7585807A846A646659524C3F3627271C0644391D6E5C38997C506F4B17BA9159 8F6326A57533CA9B55916119996A229F732C724501AC7D39BD8846BD823EE9A660C57C37AB6116 FEBA67F8B763BB7A289E6111AD7128DDA45FAE7737D69F66FFCA94CC996496612D7D4A1587521E C5905AA6713BD5A773D1B27C755E2A87703E91794BA48D636149234026053B20033E23084C2D18 3815022601005B3423875D4D481C0F61372B36130D2607041F0200290D0A1F0504170200261211 22100E1A08061C0D0A1809041908011D0C051807001604001D0C04180902160700170801190A03 180902150600160700190A03170801170801170801170801170801170801170801160901130802 130802130802130802130802130802130802130802120701120701120701120701120701120701 120701120701130502150704150704180A071608071709089284843B2D2D16070A1E0F12DFD0D5 9B8C912B1C23E6D7DE72626CB3A6ADDED4D31F1513110705110705110706100605190F0E0B0100 31272832282911060A0F0408DED3D7766B6F0B00041F1516100503100501100501100501100501 1005011005011005011005011005011005011005011005011005011005010F06010F06010F0601 0F06010F06010F06010F06010F06010F06010F06010F06010F06010F06010F06010F06010F0601 0F06011108030B020011080310070209000019100B251A18150A08150A080B0000291D1D130707 1507070F01012E1F220F03050B00011B111209000013090A2C22231B11100C02010D0302120806 1107050F07040E06030D06000C05000B04000C05000E03010E03010E03010E03010E03010E0301 0E03010E03010E03010E03010E03010E03010E03010E03010E03010E03010E02020E02020E0202 0E02020E02020E02020E02020E02020B00000D01011105051105051004040D01010C00000B0100 0D04050802020B07060602010F0E0C9F9F9D444442181816090907030301010000282725A09C9B 100C0B0C06060600000C00020A00000D03040D04050600000B07060D0C0A020200565654575956 3B3B392626240504020E0D0B0A06050201000201000E0D0B0F0E0C19181631302E0C0B09030000 100C0B0600000903030903050701030802040A04060C03064112004A1A034F19006B3008A05D30 FFC197FFBE9E9E5A47814141672D3B5D2B46592C4D4920403B1733462339502D415836475A3443 7D4E5EA36D7AB8777FD98E95CF7D81E69093DD8486DB8689D9888ED0878EBC7D86A76F7C996675 8D67747C64715B4B5847394844374942394E544C636F6A817F7C91807C8D7A7684615C626A6562 827970867D6C90856F9683639677495F38019063288B5B19C99750BF8B408E590DD8A458B17F36 915F18D7A25EE0A764DA9B56E19B56BD702ADD9146E39C4AD6943EFBBA68B77829E6A85FCB904C C48D4DB47D44CA955FBF8C57B4804EA16D3B96632E96632E86531E784A16B69260B29364D3B486 A6875B54370F5D3F1B5736172400004521094C26116338276E3F2F330200410D00400700713F34 35100820030031140E3A211C270E0A1B06031D0A061B09071809061D0E09190A051708011D0F06 1C0B031807001E0D03190A031A0B041B0C051B0C05190A03170801170801170801180902180902 180902180902180902180902180902170A02160903140903140903140903140903140903140903 140903130802130802130802130802130802130802130802130802180A07150704180A07180A07 1204031608076759592113130C0000140508B2A3A8A6979C0B0003ECDDE467576160535ADCD0D0 251B190F05031107051208071309081309080A0000443A3B4036370A00030D0206C0B5B9796E72 070000170D0E110604110602110602110602110602110602110602110602110602110602110602 110602110602110602110602110602100702100702100702100702100702100702100702100702 1007021007021007021007021007021007021007021007021209040E05000E05000D04000B0200 130A05190E0C1308061409070A0000241818110505190B0B0D0000291A1D1A0B0E14080A1C1010 0A0000160A0A2A201F1F1514170D0C1208071107050F05030E06031109061009030C05000B0400 0D06000F04020F04020F04020F04020F04020F04020F04020F04020F04020F04020F04020F0402 0F04020F04020F04020F04020F03030F03030F03030F03030F03030F03030F03030F03030C0000 0E02021004041004040F03030D01010C00000D01010F05060600001913130300004C4847747371 201F1D0D0D0B0808061212100100004E4A495753520400001A11120700000C00020E0002110507 0F05060900010B07060C0B0900000050524F63656240403E3939370000000909070B0A08040301 0909070606040E0D0B010000302C2B191514040000110B0B0A01040C03060C03060A01040A0106 0D04090D0409370200531C07551D0090552BD69869FFDFB3A06344894F41663139572741542A50 5B355E37133745243F5837485E3E4B5B3B4866424E845A66AD7E86C58C92E6A6A7DF9999DE9493 DB908DCC8583C17D7EBB7F81B07B81996C738058616D4D58503A464C3C494D414F483D4E423A4F 544F656C687F716F846D6A7D7A78865B58613E3A3B3029232C24194135274E3A1FA987599C6F34 7F4D0E95601CCE964BC38A3BB4792BFFCA7BA97126AD752BE6AD66A96D27B7742EB76E29A65810 D18338FFD383B2701CCC8B3BCD8F44C98D479E6424976125905C23F9C691D2A06FA272429E6E3E 8C5C2B6535049D6D3C9E7241A682529A7A4B8F6E4195744B502E094E2B0B9570536B432A3B0E00 491A084F1C0B96615162281C3D02006D2D236E352A421C1324070044271F412821280F0A240F0A 1805011503001A0B061E110B190C061508001C0F061B0D041709001B0D02190A031A0B041B0C05 1A0B04190A03190A03180902170801180902180902180902180902180902180902180902170A02 160903140903140903140903140903140903140903140903130802130802130802130802130802 130802130802130802160903180B05180B05110400160805110300685A59291B1B0F00030F0003 998A8FA4959A0F0007FDEEF56051583125299E9292140A080F05030F05030F0503140A080D0302 0B01005E54534F4544070000423839E9DFE07B71720C01050B0102110604110602110602110602 110602110602110602110602110602110602110602110602110602110602110602110602100702 100702100702100702100702100702100702100702100702100702100702100702100702100702 1007021007020E06030F07040B03000D0502150B091208060E0403130908170D0C120807120606 180C0C150909150909170B0B1C1010261A1A1E13110C0000180D0B231917201614231917180E0C 1006040E04020F0704140C09140D070F08020C05000E07010F04020F04020F04020F04020F0402 0F04020F04020F04020F04020F04020F04020F04020F04020F04020F04020F04020F04020F0402 0F04020F04020F04020F04020F04020F04020E03010F04021005030F04020D02000C01000D0200 0E03010A00000600001B1311120D0A706C6932312D12110D02010003020014130F0F0B08696562 1C1714060000150D0B0A00000C00000B00000E02020E0403080000090502080703000100484A45 5B5D582426214446410001000405000809040304000706020605010B0704030000140E0E171111 0600000C03040D03040D03040E02061004080F04080D02060C010558211A582313794126BC845F FFD0A49F6A426E3A2254251F471C2D553052371643270A384C30564A2E47371B294A2F3650353E 63454F836067A67D83CA9C9EF2BCBAFCC2C0E6A9A4C88B86C48985BE8985B585839E7677836064 7354596D545A56424D443643564A586C63745A526739364B3D3B515250655C5A6F6D6C7C575560 4D484E55504D59504B4C4238352109815C2FA272348A5715C68E44B87A2DDD9F4CFFC976F2B562 9358089F6416DCA057905008C68038AE641BA5550CD4863BA76012B77626DA9B4EC3873F7B4000 652D00703C03C18F5A895929E0B1837F53263D1200572C008D6235CA9F72916B3CAB8C5D523708 5A3F122C11002E10005335138A694A6E4B2F633B22481E08360700511E0B51190A400700672C1C 915C4E643E3333150B472B202E130A120000230F081E0B052715111C0D0820130B190C04140700 1B0E051A0D04160800190B00190B021A0B041A0B04190A03190A031B0C051A0B04170801180902 180902180902180902180902180902180902180902160903140903140903140903140903140903 1409031409031308021308021308021308021308021308021308021308020F02001B0E08170A04 0C00001E100D0F01008173724638370A00002C1D20DFD0D5BFB0B51B0C13EEDFE67D6E757F7075 635757070000150B091208060F0503190F0D1006051107064B4140493F3E070000695F60FFFBFC 342A2B12070B0B0102110604110602110602110602110602110602110602110602110602110602 110602110602110602110602110602110602110602100702100702100702100702100702100702 1007021007021007021007021007021007021007021007021007020901000E06030A0200110906 211715160C0A0B0100190F0E231918231918070000241A19140A09241A190C02011E14121D1311 150B090E0402221816281E1C2018151F15130700001006040E0402100805170F0C18110B110A04 0E07011108030F04020F04020F04020F04020F04020F04020F04020F04020F04020F04020F0402 0F04020F04020F04020F04020F04020F04020F04020F04020F04020F04020F04020F04020F0402 0F04021005031005030E03010C01000B00000D02000F04020F05041309080B0100261E1C66615E 030000120E0B02010003020009080426221F7D7875140C0A0800000A00001408081002020B0000 0D01011006050B03010C07040B070401000042433E4D4F4A0B0C0750514C0607020908040A0905 0605010501000A07020A0502150D0B070000180C0C1A0C0C100202120203100001130002150506 1505081000010E000157242941100C956455F3C1AAA6755772442A643A2C532F314B2B433F254C 3A24533623513E2A4F4F3C524F3A413622234D383F5F4850795E65947678C4A0A0E4BBB7EEC1BC FFDED6D2A39BAF827CB28B84A6837F917371A58B8C9E888A75626666566080727F5D515F453C4D 3F384A2A273C3D3B5153546872738783829267657269646B605A5C554B493D322E6E5944A57F50 9F6D2EA7712BBA8134A96B18E1A14AECAA53C08028BB7D28AF7221D6984B8E4C00BB76299E5206 A25004E89B4DB77426D19348F3B76F824703DEA7678E5A20784915996B3A673C1161370D3C1500 6C471D906B4165401679542A4425007563335D511F4135038F82555F50259D8E67AC9A76705C3B 947B5DAB9073412206522E14380F005A2D168B5D4661341F431E0E3616092B0D02290D02260E04 240D05210D06200F081C0D061C0D061B0E061A0D041A0D04190D01190D01190D01190B02190B02 190B02190B02190B02190B02190B02190B02190B02190B02190B02190B02190B02190B02190B02 190B02170A02170A02170A02170A02170A02170A02170A02170A02160901160901160901160901 1609011609011609011609010E0100170A021C0F090A00001D0F0C0D00007B6D6C4537360A0000 322424F6E7EAA99A9D17080DC5B6BB87787FA6979CAA9F9D160B07190E0A1106020B0000231816 0800002C211F6155553125250A00008C8080CEC2C41F13150A0000180C0C130502130600130600 130600130600130600130600130600130600130600130600130600130600130600130600110600 120701120701120701120701120701120701120701120701110600110600110600110600110600 1106001106001007021E16131A12101008060800000A0200140C091C14111F17141D151219110E 2D25220600000C07031A1511191410140F0B1914101A150F160F0919120C211A14110C060F0802 110A040E0701110A041B13101B13100F05030E04021107050D03011005031005030F04020F0402 0F04021005031106041106040F04020F04020F04020F04020F04020F04020F04020F04020F0400 0F04000F04000F04000F04000F04000F04000F04000F04000F04000F04000F04000F04000F0400 0F04000F04000E03010A00000900004E46431D18140C09040A07020805000A07020300006E6965 45403C0600000D0301150A081409071103021103020F04020D03010C0401090400080500060500 2A292453544E01000035342F2A29240D0A050C09040601000F07040F0802100604100501100100 1A08061E0A090F0000110000220A081D05031901004C34340F00000F0000451928744952A77B78 9B7165582E1E4C261952302E4125314C35514030574033613F345F392E4E3E314546373C433333 5F505575646C7A656C8A7175B79B9ADCBDBAEAC9C2EAC9C0CEACA3B08F86BA9D97AE9590A89390 C3B1AFB9A9AAA5969BF8E8F2AEA0AD4438462E2536443D4F413E51504E635F6074565769575666 5D5B68A9A3ADFFFDFFB0A6A55C514F6B56435A34059B6A28A97029C08535C88831D39238C28022 A8670BAF6F17E5A750C688359D5C0AD59140AD6211B76917EC9F4FA76318EEB269A16622793F00 C38D5193622A9A6C3B62370C7A532A59330C4C29034D2B0676563069492365451E674E25908253 877F4E948A597C714351451B3729023C2C083421004E391AC2A98B8C6E522C0A00462106754B32 4F230A4319013914023413042A0A001F0100200500260E04220E051906001E0D061C0D061C0E05 1A0D041A0E021A0E02190D01190D01190B02190B02190B02190B02190B02190B02190B02190B02 190B02190B02190B02190B02190B02190B02190B02190B02170A02170A02170A02170A02170A02 170A02170A02170A02160901160901160901160901160901160901160901160901130600130600 170A040F02001B0D0A120401837574887A790A00004B3D3DFFF1F47C6D700A0000BDAEB3988990 423336C9BEBC1C110D0D0200130804130806180D0B080000554A48463A3A180C0C080000716565 A4989A080000120608170B0B130502130600130600130600130600130600130600130600130600 130600130600130600130600130600130600130600140701120701120701120701120701120701 120701120701110600110600110600110600110600110600110600110602190F0D1109070E0604 130B08160E0B120A0708030004000023201B25221B2B282318181007070017181016160E0B0C04 14140C1212080E0E061C19121E1B14100D06110E07110C06110C06150E08201815201815150B09 1107051208060C02001106041005031005030F04020F04021005031106041106040F04020F0402 0F04020F04020F04020F04020F04020F04020F04000F04000F04000F04000F04000F04000F0400 0F04000F04000F04000F04000F04000F04000F04000F04000F04000F04020E0301160B09493F3D 18100D0E09050803000B08030704001916115E59552B23200800000F05030D0200140605110302 1103020F04020E03010D03010B030009040008050016130E4946410B08033B3833403B37191410 221A172B221D0900001A0D070B00000E00001A0500341B176245412B0C091E00001D0000270601 3B1D1553352D3518102003006441577D5B6B78555C4D2B2C3E1C1A2F0F102C11182E17291E0E2B 1E1439332C55443E643D3753382F403F343A4236386E636B9A8D968A7B827E6E71A49091E1CCC9 FEE6E2CEB7B1B9A099A68F87BDA8A3B5A29EBCAAA8C5B7B792868A82757C887883594B58342836 3F36473B34462623364F4D6288869B9B9AACD7D6E49997A45F5963928C90675D5E3E3232422D1C 825C2BBD8C49BE863CCB913FD99941DE9C3ECA8625A86605F8B759FFC568C88B32B2721ABD7A23 BA721DDB8F39D08532E2A054B47830480D007D4606855118A57340A276473C12007E5831876540 5837145638164D300E523513C8AE89D0B990D5C095806E409A875C6A572D47310A49330E614927 4329088F72548664483C17004B210862341A2F00004D1A004A1A031F0000260100310D00321205 2C1004270C01250E062511081E0D051C0E051C0E051C0E051B0D021B0D021B0D001A0C00190B00 190B00190B00190B00190B00190B00190B00190B00190B00190B00190B00190B00190B00190B00 190B00190B02180902180902180902180902180902180902180902180902170801170801170801 1708011708011708011708011708011A0D051205001508001508001407010B0000655754A89A97 0B00004B3D3DF6E7EA695A5D0A00009B8C91A29398150609B6A8A71F120C120401180A07160805 1002000A00007163625345440A00000A0000867878A597970F01011D0F0F100201150603150601 150601150601150601150601150601150601150601150601150601150601150601150601150601 140701140701140701140701140701140701140701140701140701130600130600130600130600 1306001306001306001106021208061D13111A100E08000008000017120C1A17100C0C04181911 23251A24271E313429050B00141C0F1E24180D15080A1004070D00060C0022251A1B1D120A0C01 1010060C0C0214110A130E081D15121E16131309070F05031106040B0000110604110604100503 1005031005031005031106041106040F04020F04020F04020F04020F04020F04020F04020F0402 0F04000F04000F04000F04000F04000F04000F04000F04000F04000F04000F04000F04000F0400 0F04000F04000F04001204030F04022116143C3230100805130E0A0500000F0A06060100312C28 443C390C04010F05031005030A00001204031103021103020F04020F04020D03010C04010A0501 0A0501120D093E39350E060328201D403634170C0A3022214F403D3B2A230F0000240D052C130C 2708032000004C251E7B534B4A2218210000350B0050291A512C1C2400001B00004B32474A3144 5B3F4D6C505C9678826F535F51394949364A3C2F4B2D2345262042221F3E1F1A312C25373F3540 4338406A5E6A938793938690AA9BA2BAAAADCFBDBDE5D3D1AE9B97A3908C9C8985BDABA9C4B2B2 E6D6D7F0E1E6A4959C90838C7868755C4B5B534657594E5F3932441C172B3B384B69687A8D8C9C CECCDA615E691D181F42393E756B6C5D4F4F3D26168D67369E6D2ABC873BBD8331B5751BDE9C3B EAA641C88721FFC15DC78B29AD71119C5F02AC6B0FD79537F0A94DCF8830D693458F5009925512 BF85467A430BA97744572B004A20004A24007957327153314D300E4A2D0D795F3C9D8360D6BC97 FEE1B981613A8767419D7D57502F0E51300F7350328E694C7E543B3E12008A5A43B48068794128 59200584482EA870596C3F2C4E27163A15053612042E0E012105002109002E170F200D061F0E06 1E0D051C0E051C0E031B0D021B0D001B0D001A0C011A0C011A0C011A0C011A0C011A0C011A0C01 1A0C011A0C011A0C011A0C011A0C011A0C011A0C011A0C011A0C01190B02190A03190A03190A03 190A03190A03190A03190A03180902180902180902180902180902180902180902180902170A02 120500170A021A0D051306000A0000392B2890827F130504231514D2C4C486777A0C0002736469 9D8E935041446658551205001E100D1709061204011507041103026C5E5D6254530A00001F1111 D2C4C4AFA1A1190B0B170909120403160704160702160702160702160702160702160702160702 160702160702160702160702160702160702160702160702150802150802150802150802150802 150802150802150802140701140701140701140701140701140701140701140701160B07211715 211715110A040601000E0B041C1C1425271C13160B2026182D3526434E3E121F0E0E1D0A2A3926 142310081605091605061302313C2C20281B080E020E11060A0C011B1B1314110A16110D170F0C 0F05030F0402150A08130806120705120705110604100503100503100503100503110604100503 100503100503100503100503100503100503100503100501100501100501100501100501100501 1005011005011005011005011005011005011005011005011005011005011305040F0100241615 291E1C0B01001B13100600000F0A060702002B2622251D1A070000150A080C01000E00000F0100 1103021103020F04020F04020E04020E04020D05020C0401130B083026240C01001406053C2C2C 0C00001D0B0B3C29256C534C583D341F0100290800502A21350A012900007644398251434B1807 511E0B7F4F399E7059471B02380C0024162320101D2F1A29291222412637452A3D563D524C394F 42344D352B44272239211C332F273E4E455A584B5D443647695B6C7A6C7DA496A5F9ECF6F2E2EC BCABB1BFAFB2A18F8FAF9D9DA99797BAA7A9C3B0B4F8E5EBFFF8FFC7B3BFAE9CAA7B6977675666 63556660536551485B4C4859575465666374504D5E42404D34313A7A737A72676B453939443635 7962505C360582530FD49F53BB812DA46508C78723C98820CB8C22DDA036BF841EAF7410A26604 E1A241EEAE4CF3AF4EE49F42CE8A39C9873DA66521874A09753D0296612B3B0B00784B21B08960 57340E4827045B3D194628069E825DA185607B5A37946946A07250916342885A39532408613216 6230176E3C235D270F7D432DC88B76C7867093513B98513B974F39AE6D5750200C4218083E1706 4E2919603E325D3F3441261D240C02210D04200E04200E041E0D031E0D031E0D031D0D001D0D00 1A0C011A0C011A0C011A0C011A0C011A0C011A0C011A0C011A0C011A0C011A0C011A0C011A0C01 1A0C011A0C011A0C01190B02190B02190B02190B02190B02190B02190B02190B02180A01180A01 180A01180A01180A01180A01180A01180A01120500140700170A02190C04180B05190C06281A17 6F615E0E00000D0000C2B4B4A193930B0000716265A192978A7B7E483A370D00001C0F09130600 13050220120F190B085A4C494436350E0000392B2AFDEFEE7B6D6D0A00000B00001F1110160702 160700160700160700160700160700160700160700160700160700160700160700160700160700 160700160700150800150800150800150800150800150800150800150800140700140700140700 140700140700140700140700140701190E0A1106021A110C2C251D231F16090600050700171B0D 1A2213212C1B404F3C4F614B2D402A0F250E354B341D331C0E240F192C180D200C4354412D3A29 0914040810030C0F0427282019160F140F0B150D0A0F0503140907211313241616130806130806 120705110604100503100503100503110604100503100503100503100503100503100503100503 100503100501100500100500100500100500100500100500100500100500100500100500100500 1005001005001005001005001305020C00001B0D0A170C080B02001E17110902000E07010D0600 140D07100702080000160B070A00001809060E00001103000F04000F04000F04000E05000E0500 0E05000F06010900001C0E0B0F000016040246323116010011000014000043251D836157734D42 210000380800804C3F2900005C2111AB6E5C925540581C02834A2DB17A5B703B194D1B001C161A 1E141C3527343924352E152B2C102930162F19031A1C0D202318292D2435362F3F4D44596C6078 63536E3B2943503E5469586BA796A8E9D8E8D6C6D1BFAEB8C9B8BEA18E94A69397AF9A9FAE99A0 AF9AA3D9C1CEE7CFDDB39BAB8E7588836E7F7E6B7E847386746779655C6F615A6C5D596A6E6C7A 4F4D5B55515F77717B524B52352A2E3F3131665656553E2C573301A47733E6B266BC842FC78A2D CE8F28AE6E04C6881BE1A439D89F34CC932CD39A33EBB04AD99B36FFBF59DA9635C57F2AC78235 7F3B009A5917B6783B9B622B85511F72421481562C350E00603D17AF8D686848225D3F197F613B 4826014E2200A47352C998788B5C3E6B3C2086573B9E6C5379452D7B452D9B634C6A2E1663250E 77351D8B482E833D244A09006C39267045345B31212F080023000037170A3A1E13250D03240D05 210D04210D04200E041F0D031F0D031F0D011F0D011D0C021B0D021B0D021B0D021B0D021B0D02 1B0D021B0D021B0D021B0D021B0D021B0D021B0D021B0D021B0D021B0D021A0C031A0C031A0C03 1A0C031A0C031A0C031A0C031A0C03190B02190B02190B02190B02190B02190B02190B02190B02 170A011A0D041609011003001508021A0D072618155446430A00002F2120E0D2D29688880A0000 847578C0B1B68071747C6E6B1F120C1508021508021709061C0E0B11030040322F2D1F1E110302 302221E3D5D43628280C00001204041D0F0E170803170801170801170801170801170801170801 170801170801170801170801170801170801170801170801170801160901160901160901160901 1609011609011609011609011508001508001508001508001508001508001508001508000E0300 150A04170E0719120A231F162A2A1E1F2114080F00141F0E12210C3D503A4E654B4961472C462B 4461453451351A341B2E47311129134D634E374836081605010C00121A0D28292114140C0E0905 130907100503150706211112241415160807140907120705110604100503100503100503110604 110604110604110604110604110604110604110604110602110602110600110600110600110600 1106001106001106001106001106001106001106001106001106001106001106001203000F0000 10020010020010050119100B0D04000C05000F08020600000D0400110602180A070A00001A0B08 0F01001103000F04000F04000F04000F06010F06010F06011005010D0000110200110000110000 3F27272B11121F02041E00002400003E160A8A5E538150422700005D22126A2B1A5B18057A361F B9765B955235B77754C48661B2774F70370C2B2A251D19181B10182E1C2C2D142A30142D31152E 371E334230403E303D3A2E382F25302F223644344F4E385C3D274B38243F4F3C5289768A9D8A9D 8E7C8AB7A3AFCFBBC698838C8D7881B099A3AB919EA98E9DBEA1B3CEAEC3C5A5BA9C7F959A8397 7D6A7D71607368596C716579766F8184808FC3BFCEC1BDCB403D48332E35433A3F706466887A79 786966533D2865410FB98C48D19D51B57D26D69A3AD5962FD59529D99B2CC28918B98112CB9529 DBA53BCA9128DAA035F7B84EC17D1ADC923BAE6214AF651ACD8942AD6C2CA3662DDDA670A67242 9F7044552A00845D34744E27C7A47CA5845B57360D805F364D2A045F3915B48D6C876341512D0D 2D09005C35188A6346734A2E6B3F247344283000004D17009E6749874E303D0500390900582A1A 6035254016082300002604002F11072E130A250C05220E05210D04210D04210D04200C03200C01 1F0D011D0C021B0D021B0D021B0D021B0D021B0D021B0D021B0D021B0D021B0D021B0D021B0D02 1B0D021B0D021B0D021B0D021A0C031A0C031A0C031A0C031A0C031A0C031A0C031A0C03190B02 190B02190B02190B02190B02190B02190B02190B021A0D041E1108180B03100300140700100300 2E201D4C3E3B0F01005C4E4DFFF7F76E60600C00006A5B5EDDCED15A4C4C928481231610140701 1B0E081407011609030E00002F211E332522140603281A19CCBEBD221414190B0B1D0F0F140605 180904180902180902180902180902180902180902180902180902180902180902180902180902 180902180902180902160901160901160901160901160901160901160901160901150800150800 1508001508001508001508001508001508000C00001C110B160D06060000130F043A3B2D404435 252E1B101D090618002C4329516B4E617E605F7E5F5677585475562F4D334C6A501C382158715B 465B481122100612042732241E21180C0C040B0602150B09120705120403170708160607170908 140907130806120705110604100503100503100503110604110604110604110604110604110604 110604110602110602110600110600110600110600110600110600110600110600110600110600 1106001106001106001106001106001102001607040B00000F0100150A060D04001007020E0500 1007020D04001B100C0E0300190B080E00001304011406031103000F04000F0400100501100501 1106021106021305021809061301001904031100002A0D0F3B1D1F412124472323471F173C0E01 3D0C00B7827474392B3000009C5843570F0071270C9047279B52317C3710975429C38355C08251 1C171430272A2417212B182B29132A351D372A122C39233A49384A483A49493D493C31412A1C33 30203D4430554B355B5A4262462F4B7F6882A38BA3957E92B39CACC4ACBA9F8794A08693CCB0BE B69AA9A68799A58499B997AFDEBBD3C0A0B76853665648595D5062594E5F4C4557393448605D6E DCD9EAE0DEEC7C7984726B737E73796153536A585635221C41281285612FCFA55DDDAD59CE993B C48B22B87C0EFABB4ADC9D2CAC7002BB8115DBA539D39D33DAA33CFFD26EB98120A96C11BC7823 844000EBA85AC080389D601FDAA265BE89537344108B5F30562D01B59066947147BE9D7276552A 86653C65451C5A3C166A4E29876A48391C00442A09452B0A1F0400593C1EA485688C6A4E654025 461F027346297243279F6E506C391E4512004514034E1F0F562B1B4A2314300E02220400240900 250D03220E05220E05210D04210D04200C03200C01200C011D0C021B0D021B0D021B0D021B0D02 1B0D021B0D021B0D021B0D021B0D021B0D021B0D021B0D021B0D021B0D021B0D021A0C031A0C03 1A0C031A0C031A0C031A0C031A0C031A0C03190B02190B02190B02190B02190B02190B02190B02 190B02150700190C031D0E071A0D051D10081003003F322C594B481406056B5D5CFFFBFB4A3C3C 0B0000302124E2D3D6453737685A570F02001508001F120A1003001A0D051D100A332522372926 1608073B2D2DDBCDCD2D1F1F100201180A09170906180904180902180902180902180902180902 180902180902180902180902180902180902180902180902180902180902160901160901160901 160901160901160901160901160901150800150800150800150800150800150800150800150800 1B0C070F02000E04001B13081C180C1A1B0B2E322147533D202F180E25092943265C7B5C729575 86AB8A5D8563638C6C446B4C698D712B4D3264856A58745D1F372113261343503F182013090C03 0E0B041C14111B100E1608071202030D0000170908140905130806120703110604100501100503 100501110604110602110604110602110604110602110604110602110600110600110600110600 110600110600110600110600110600110600110600110600110600110600110600110600100200 1C0E0B0B0000130502180D090800001108030F06010E05001E1510281D190800001B0D0A150704 0A00001709061103001103000F0400100501100501110602130502130502120300130000270F0F 1E0103240407452226532C31592F30602F286F3B2E90584B6B3022A3645565210E3D000096492F 9744266F1B00D17E569D4C1FED9F6FF9AD7BEAA16E2614222614242714272A172D2A18322B1B36 37274243354F423851594F68544A63382E472C1F3B342743493A59604C6F58406452385D624969 A88EAB91758EAE92A8E0C3D5B599A8A18291CBABBAF0CFE0C1A0B39E7B91906D85B38FA9B496AE 6B5D6C5C56625F5B693D3A4B4443554F5064434459818296848395FFFCFFC1B9C4372B2F4B3939 2A15103E251E54382094703E976F27D8AD4FBB8C20D8A42CE1A72CE2A32FD08E20C9861DD5962F D79C34D39C37FFCB6DEFBD6892621A905E177E4900B6822FC89546905E15B88945C99D5E8A6227 4B26004420006646178E6F43D5B88E7D603643260081643C8A6E47553B18654E2E756140291500 4A37174A3A193323029885653F2A0D886E5384664C3B17007D533DA879655825126C3423905746 5D2516440F01552517582E20391509220400250D01250F04230F04230F06210F05220E03210D02 230D02230D021F0D011E0E011E0E011E0E011E0E011E0E011E0E011E0E011D0D001E0E011E0E01 1F0F021F0F021E0E011E0E011D0C021D0C041D0C041D0C041D0C041D0C041D0C041D0C041D0C04 1C0B031C0B031C0B031C0B031C0B031C0B031C0B031C0B031B0A021A0C031B0A021C0E05190A03 1708013728236A5B580D00007A6C6BFFF4F430222215090B392D2FE6DADC766A6A3628251A0D05 1508001F1209170B0022150C0A0000392C2655474611020596878CFFF2F51709081B0D0A120500 1D1007180B03180B03180B03180B03180B03180B03180B03180B03170A02170A02170A02170A02 170A02170A02170A02170A02170A02170A02170A02170A02170A02170A02170A02170A02160901 160901160901160901160901160901160901170801150300200E0A1B0C05180E042B2517363725 31362026321A63775C314B2E153415547958749D7D97C4A575A48468997960926F6D9F7C41704E 7DA98879A08308290E4A644B475A44152210060C000C0C02332E28140B061507062C1C1D201010 140603120701120703120701120703110600110602100500120703120701120703120701120703 120701120703120701110600110600110600110600110600110600110600110600120701120701 120701120701120701120701120701120701120701160B05160B051005000F0400130802120701 0D0200140903140903130802120701110600110600100500110400120300120300120500130600 1207011207011207011306001304001E0B07341A194828294F282B481E2247181E4C1A1B5F261F 5B1F14490B005E1E12AC685B934C3A4B0000741F02C46642A9481DB04C1BD97541DB7A47E38551 D37945341B31351D33331D34331F383D2D474B3D574C3F5B423755352C4B463D5C5146665A4F6D 695C7A615470463653321F3F755C8390769D7A5F828D72918D708CB89BB1F6D7E9C4A5B4B797A6 DEBCCCE8C6D7E5C3D4B996ACAD8AA294708A8C70877A6E7C8C8994716F7C4F4E5E3F405436384D 37394E2D2F443D3C4E736F7E5A50592F2025422E2D412A22775C51C2A48C68431689611BCEA345 AA7C0CD9A72AE8B132FFC854C78316B6710AE5A440DB9D36CC9530FFE084FFDC8C936726A5793A A27427D6A956C29446714700BE9651D7B1728F6C325C3D064B2D008C7041A88D62957A4F8C7048 93774F6D50288165405039195944252C19005343224F40216356366053334536171F0E00695439 341A033C1C07340E009A6C5C5E2D1E521D0F864C3E692F21531E10502012491F13341206260A00 240C00230F04221004221006210F05220E03220E03230D02230D021F0D011E0E011E0E011E0E01 1E0E011E0E011E0E011E0E011D0D001E0E011F0F021F0F021F0F021F0F021E0E011D0D001D0C02 1D0C041D0C041D0C041D0C041D0C041D0C041D0C041C0B031C0B031C0B031C0B031C0B031C0B03 1C0B031C0B031B0A021C0B031C0B031D0C041A0B041809023627226657520C00005F5150FAECEC 332525100406584C4EFFFBFD6E6262221411170A02170A01180C000E02001F13071407003B2E28 4B3D3D140508E0D1D6AD9EA30D00002316101509001D1105180B02180B03180B03180B03180B03 180B03180B03180B03170A02170A02170A02170A02170A02170A02170A02170A02170A02170A02 170A02170A02170A02170A02170A02170A02160901160901160901160901160901160901160901 170801190602200D071B0A03180C00231D0F2B2A16282D1628351B25391D849F804365441E4322 75A1809AC7A88BB99C679878699D7984B8924A7C5790BF9B79A5841E43246482665F775D031401 192413474A3F0401001D140F231512180808251515170906140903130802130802130802130802 140903140903120701120701120701120701120701120701120701120701110600110600110600 110600110600110600110600110600120701120701120701120701120701120701120701120701 120701160B05150A041106001005001308021207010E0300140903140903130802130802120701 110600100500120500160702160702150601140701110600110600100500100500150601140100 1C02012E0E0F42191D4A1D224F1E24551E21480D057335286F3126470700722E21AB5F4F88341C 660900B14B25C25628C75521D4612BC65720DB6D38DD75422F172D362035351F362F1B34382842 4C3E584D405C40334F4035534C415F4D405E4839584A39594D3D5A5C4766715C7B452B5070567B 715878967C99BB9FB8C3A8BBEED2E1D1B2C1D7B8C7ECCCD9E5C5D4EECDDED3B0C4B895AB916E86 997C9287798879717E595361504C5B5E5B6E73718678768B525065605D6E443E4C3A3038453639 4C3935543D355E463A8D6F57B08960AC8041E5B962E2B349FDCB52C68E13DA9C2B9F5C00BB7712 F6B54FD2952BE1AB41FFD16EDBAD5593671EA77A369D6F21E6B968815306986E24CCA560977434 8D6A3084652F917243A3875891764B7D6139866A43280C00896D46462C07533A1B382304443113 9B8A6C7465465041224436196D5E41604F33614D322C14003213002A05004F2614683A2A2F0000 693625663322572818431808350F022F0F022A1003240E01221004211006211006221006220E05 220E05240E03210D02200E021F0F021F0F021F0F021F0F021F0F021F0F021F0F021E0E011E0E01 1F0F022010032010031F0F021E0E011E0E011E0D031E0D031E0D031E0D031E0D031E0D031E0D03 1E0D031D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C021B0A021D0C041C0B031E0D05 1C0B041A090233241F5F504B1B0D0A453734ECDEDD3C2E2D080000534747FFF3F54E42421D0F0C 170801190B021F11061305001C0E0123150C48393434242517070AF8E7ED6353560B0000251611 1B0D021B0D02190C03190C04190C04190C04190C04190C04190C04190C04180B03180B03180B03 180B03180B03180B03180B03180B03190B02190B02190B02190B02190B02190B02190B02190B02 180A01180A01180A01180A01180A01180A01180A011809021502001A0701180700190D01221A0D 2524102F331C404A2F546447475F3F819F7D3A5C39648967A3CCAA8FBB9A80AD8C7EAC888CBA95 67957097C39F79A28041664588A98C3F5C401329145C6B5821271B2D2D2327201A1B100C0F0000 1A0808180906160903150802150802150802160903170A04170A04140701140701140701140701 140701140701140701140701140701140701140701140701140701140701140701140701140701 140701140701140701140701140701140701140701150802170A04170A04130600130600150802 140701110400160903160903150802150802140701130600130600130600180904170803150601 1306001106001207011209021409030E00001704002008062002021C00002400003D1015592728 551C1555190E62261C56160C561205813424964029983619AF431DE77246F07643FF8450E26632 D65E29D86230291328311E323320362A182E28162E31213B3D2F49433451695A796857775F4E6E 5E4B696651706A5370725977836A887057777B628291789699819BB79EB3C5AABBEED4E1EDD1DD EACEDAEBCDD9E8CAD6DABAC9E2C1D2B592A6BF9CB2E9CCE0BAA8B6746874766A785449592E2739 373246373246585465746D7D68606D796E744D3D3E321F193F291E3A231550321A7D532D95662E E6B966E9B953FCC956F4BC45EDAF40A46300D79630F7B851C98F23FFD567D7A83E8256009A701E A4782DC59847DBAE5D926719E5BB7398712E765214B8955DBF9F6CAE8F61AB8E62654921311500 8D714A5F431C92764F3319003A2102351E00523D2053402289785A5748292113004B3D20908164 463519321C04260C00492914220000754C3A4B200F491B0B4F2111481E0E3611012909002A0E02 291306251106221107221107211006211006221006220E05240E03220E03210F03201003201003 2010032010032010032010032010031F0F021F0F022010032010032010032010031F0F021F0F02 1F0E041F0E041F0E041F0E041F0E041F0E041F0E041F0E041E0D031E0D031E0D031E0D031E0D03 1E0D031E0D031E0D031B0A021E0D051D0C041D0C041D0C051B0A032F201B5647420F0100332522 D8CAC94436350F0303423636E6DADC594B4B24151217080115070027190C1E11011608002E2017 4C3D381A0A0B19090CCFBEC458484B0B00001E0F081E10051608001A0D041A0D051A0D051A0D05 1A0D051A0D051A0D051A0D05190C04190C04190C04190C04190C04190C04190C04190C041A0C03 1A0C031A0C031A0C031A0C031A0C031A0C031A0C03190B02190B02190B02190B02190B02190B02 190B02190B021503001807001607001A0E021E17071D1A072F311B4E573A4A57396F836068805C 86A27C4A6A4584A884ACD0AC8BB18C93B9949BC3A0729A77AAD2AF678F6D82A786789B7D092A0D 415A441629153742322F3227130E08100501210F0F100000150601150802170A04180B05180B05 170A04160903150802150802150802150802150802150802150802150802150802150802150802 150802150802150802150802150802150802150802150802150802150802150802150802150802 150802160903160903160903150802140701140701140701130600160903160903160903150802 150802140701140701130600170501160400130400130600120701150A04180F081B100A271A14 2614102C17144026255232334E2A2C370E12220000370500430A00682F24793D326D291E762A1A 933B25A64125B13F1BE0653BE2602FFF8A57F36D3AC03D09B937062A172A2A192B301F32352339 3220382F1D373828434A3753624F6D7964838A72928E7593886B8A765776725372806381A58CAA 9F88A4CCB5CF9E869C9A8395D5BDCBFBE4EEF4DDE5EDD3DCE7CCD5E3C8D1D9BBC7E3C4D3B998A9 CEADC0FFEAFCD5BDCB614D594E3C4A4837473B2E403F334725192D2C213213081871656FDFD0D5 8C7A7A58443D3F291C341D0D4B2B14663A1785531EE8B96BF9C967F4C052FFD763D6992EB4750E E6A642EDAF48DCA435FFDA67C89A2B7E5300A97D24C39945F3C675BB8D3FCDA156A07830320B00 886428C3A26DBE9E6DAA8B5F775A32311500684C27684C27735732573B163D2300482F114E361A 3C270A2E1B00A19072655637332508281A0072644938280E2410002E16003A1E092D0C004C2916 593422360F00371200361202301001290F02250F02241005231208221107201209201209211008 221006230F06240D05220E05210F03201003201003201003201003201003201003201003201003 2010032111042111042111042111042010032010031F0E041F0E041F0E041F0E041F0E041F0E04 1F0E041F0E041E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031D0B01200E041D0C04 1D0C041E0D051B0A032B1C174D3E3917080570615EEFE1E0493B3A1A0C0C302222C7B9B95A4C4B 1A0B061C0E051406001E10031B0E001D0F024234293B2C271202032B1B1ED3C2C8645457110200 1B0C051C0E031709001B0D041B0D041B0D041B0D041B0D041B0D041B0D041B0D041A0C031A0C03 1A0C031A0C031A0C031A0C031A0C031A0C031A0C031A0C031A0C031A0C031A0C031A0C031A0C03 1A0C03190B02190B02190B02190B02190B02190B02190B02190B021D0B071D0C05180902180C00 160D00100B0021210943472C6A73544654319BAD87899F787B946C415D35B9D5AD97B68D9FBD99 C5E3C1739270C2E4C1729775B0D5B432593A1C412242624A4E6751394A38030B001D1A13150A06 0D000023110F170803180B031C0F071F120A1E11091B0E06170A02130600150800150800150800 150800150800150800150800150800150800150800150800150800150800150800150800150800 150800150800150800150800150800150800150800150800160901150800150800160901160901 140700140700150800160901160901160901150800150800150800150800140700170600170600 140500130600130900160C03180F061A1108382E25392C2436251E2E19142C130F351715472524 56302D380C033B0B004A160B682F2474342A6C2314802814A53D22C44E2ADC5B31C43A0BF56533 ED5B2AC43402C0320229182A200F212615283B2A3D463349402C45412D484E37544C3351735877 8E71908A6B8A7F5C7C7D5877987392BC9BB6AE94AFA08DA3E0CADFCEB9CABBA7B3E3CFDAF4E1E7 F6E1E6F2DBE1F0D9DFDFC5CEEFD4DDD3B7C3B596A5A08191C8A9B9B599A7886E7B735B69806979 6654644B3A4C4A394B2E202F30202D63535DA49497503C3B48342B422B1D5137287252395A2C08 713E07D7A659FFD573F6C254FFD765C48B20E7AC46E7AC48EBB24BFEC85BEBB948D1A333B3881F B08527E4B762E3B665D2A758AE82373D1500663E00926E34A3824FA3845644270051350E755934 8B6E4C462907B99D78CAAE899A805D50371929110031190035220468573968593A2A1C00221400 45371C39290F3120062814002C1300361B062307003A1B073213002D0E002A0F002F15062C1609 241206200F051F110621130A201209201209221109221006230F06250E06230F04221004211104 211104211104211104211104211104211104201003211104221205221205221205221205211104 201003200F05200F05200F05200F05200F05200F05200F05200F051F0E041F0E041F0E041F0E04 1F0E041F0E041F0E041F0E041D0B01210F051E0D051D0C041F0E061C0B032A19124435302A1B18 C8B9B6FFFBFA3D2F2E150707251717B7A9A94C3E3D0C0000281A111D0F04130500170A002D1F12 5E50452A1B141808085C4C4FFFF4FA5444471607041F10091A0C001D0F021C0E031C0E051E0D05 1C0E051E0D051C0E051E0D051C0E051D0C041B0D041D0C041B0D041D0C041B0D041D0C041B0D04 1B0D041B0D041B0D041B0D041B0D041B0D041B0D041B0D041A0C031A0C031A0C031A0C031A0C03 1A0C031A0C031A0C031D0C051F0E07190B02180C00170E00130C00211F08404024666B4B98A27F 67734D83946ABCCEA486986E5D7247C7DCB3A6BA95CDE1BE94AC8AADCBA9B6D8B585AA88173F1D 5E85665A7E643250380010002A352501010011080333211F0E00001D0E071F120A22150D251810 23160E1F120A190C04150800160901160901160901160901160901160901160901160901160901 160901160901160901160901160901160901160901160901160901160901160901160901160901 160901160901170A02140700140700170A02170A02140700140700170A02160901160901160901 1609011609011508001508001607001B0A031A0902170801150800150800130900140B02140B02 180E050F05000E0000200F083D28234D34304125222D0E094A251C471F13370B025422177A4035 773223822D189C371BD55E3CF7744ADB4D1FEC5828F15A2BEA5324DE4A1C2C1A2A2917272F1C2F 3F2C404C364D523A5459405D6248656B4E6C7859787F5C7C8C6786AE87A4C69EB9CA9FBBC5A1BB D9C0D6D2C1D3E0CEDEF5E3F1E7D6E0E5D4DCF2E1E7FFF9FCFAE7EBF7E4E6EDD8DDF5DEE6CAB0B9 AB8F9B947682A587939878857C5E6A6D4E5D7F63727F67777A637376617054404C46323D2B181E 372324230E09402A1F4C35254D33225233175627009E682CEAB764E2B14BD09E2DF3C04DC08A20 D7A03CEFB957EDB753FFD469E2B244CE9F33B3861FD1A449EFC26FD9AC5BE7BC6E7B4F06734B06 CBA5678E6B35A07E508C6D413E2000472A08977A5A563C1B644A29A88E6B684E2B9A805F644B2D 3D2509442C122A16003E2D11AC9D8067593E291B002214002719003929101D0B0037230B331D06 2F16003219032E15012B14022813002714032715072616092113081E110820130A21130A201209 221109231107230F06250F04230F04231105231103231103231103231103231103231103231103 221002221002231103241204241204231103221002221002221004221004221004221004221004 221004221004221004210F03210F03210F03210F03210F03210F03210F03210F031D0B01221006 200E041E0C02200D061D0C0427160F3F2E271F100BDBCCC7F5E6E3261714150706332524DACCCC 685A590F00002C1B131F0E041C0C0020100129190A65544A27160F190707A69395FBE8EC2E1B1D 1C0A081E0D062010032010031F0E041F0E04200E041F0E04200E041F0E04200E041F0E041F0D03 1E0D031F0D031E0D031F0D031E0D031F0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D03 1E0D031E0D031D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C041908011E0D06190B02 190B001D11031D150229230B3F3B20686949797D5A99A077737C519BA67BDDE9BB7C895BAFBC90 AAB48FB0BC98B8C8A4B1C9A5D5F3D14E71504C74527BA484466D52001E06263D291B281734342A 29201924120E29161224130C23140D24150E24150E22130C1E0F081A0B04180902170801170801 170801170801170801170801170801170801180902180902180902180902180902180902180902 180902170801170801170801170801170801170801170801170801190A03150600150600190A03 190A03150600150600190A031708011708011708011708011708011708011708011708011A0902 1A09021708011609011508001208001108001108000B0200140A011C0F071C0D06200F082C1712 38201C3D241F240900503325523026562E22703E338B4D3E984A347F2004BA4927F3744BEE6436 EB5928EC5526F45D2ED945173C27384631424D384B4B34484E354B5F435C785A768A69868B6888 9974939972919B7290B489A5C69AB5C092AEB28AA2BAA3B5F1E0F0D9C9D6F7EAF4FEF1F8F9EDF1 FFF5F7FFF4F6FAECECF2E2E3FFEFF3EBD6DBD0B9C1AB919ABFA3AFCFB1BB9A7984795863906E7C 7656635D3E4D654957604653856E78664F57372124371F1D3D262031190D3F2514482F19543314 744413B17B35E8B55AEDBA4FE4B33DD7A532C6932AFDC966FBC96AEBB95AF6C75FFACB61C1952C 865800FFD682F8C97BD4A65891651A633900BF96568D662D6C48169472454323001C0000795C3C 94795B84694B4B30124E34134F35143D23025B4224543A1F1E0600311C0144301575644887775D 4D3F24291B00281A002A1A012A1A012B19012612002612002914002611002A18042716041F0F00 1D100025170A25190D1F120920130A21130A23120A231107241007230F04250F04250F02241103 231103231103231103231103231103231103231103221002231103231103241204241204231103 231103221002221004221004221004221004221004221004221004221004210F03210F03210F03 210F03210F03210F03210F03210F031E0C02221006200E041E0C02200D061E0B0425140D3B2A23 301E1ADBCCC7D9CAC71F100D190B0A362827ECDEDE7969691A0804200F07130200271708271707 11010052413727160F110000DDCACCBAA7AB1200011F0D0B16050028180B1D0D00200E02200E02 200E04200E02200E04200E02200E04200E021F0D031F0D011F0D031F0D011F0D031F0D011F0D03 1F0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031D0C021D0C021D0C021D0C02 1D0C021D0C021D0C021D0C021A0901200F071A0C031608001A0E001C11002018012E290C4C492A 6D6A47777751B0B38896996C8F9565CDD3A3A5AB7DAEB089A1A582B9C3A0ECFDD9B1CBA8527451 8EB392709979436A4D8FAF97889F8B77847359594F352C25200E0A2A171126150E23140D21120B 1E0F081B0C05190A03180902170801170801170801170801170801170801170801170801170801 180902180902180902180902180902180902180902180902170801170801170801170801170801 170801170801170801190A03140500150600190A03190A031506001506001A0B04170801170801 170801170801170801170801170801170801160500160500160700160901160901140A01130A01 120900120900160D04160C0312050013040019080119060014010026140613000012000035180A 3008002B0000702C17A24C319D3512DB643CEB683CE15728DD4F21E85A2CD041155139496B5363 664B5E5A3E54684A62674661603E59724E6A7C5373825775946784986C879D6F8BA2728CC191A9 D7B0C5CCB6C3E2D5DFF4E7F0F9EEF4FFF7FDFFFBFFFFF9FAFFFCFAFBF1F0FFF4F4FFFBFBE9D9DA BAA5AADEC7CDCDB3BCB89AA4A37F89B58F9AA37D8876525E5F3D4B59394646283230121A5A3F44 63494A5B423D442920351B0C391E0B3F250E4523006A3800AC7322F9C45EE7B542E0AF36D5A72F B08117FACA68FFDB81F2C369FFD474E3B553875900CB9C42FFF9ACC18F46A375286337008D621D B0884A472000A783536D4C23300F0048290C87694D5A3F24280D00543B1D7B6243341A00402507 41270C6E543B624A30261100301C039D8C72503F251808003020072D1D042A1A01291900291902 2A180229170127150027160226170226170423160523160622140722140922140927191027160E 241309231107230F04261003281004271104241103231103231103241204241204241204251305 251305231103241204241204251305251305241204241204231103241206241206241206241206 2412062412062412062412062210042210042210042210042210042210042210042210041F0B00 210D02251106251106200E041F0D032A171036251E25130F94827EDECFCC1B0C091A0A0A453535 EADADA75666324130C25140A1909002212032515052111022A1A0D25140D1301019380829E8B8F 0E00002816121E0D051909002B1B0C200E00200D00200C01210E00220E03220F01210D02200D00 1F0B00251204261207210E001F0B00241103251106210F031F0E041F0E041F0E041F0E041F0E04 1F0E041F0E041F0E041A09001F0E042110061D0C021A09001C0B011D0C021C0B0124130B1E0D05 190B02190B00180A00160B00180D001B14002E270A4A44226E6A44807F53A09F71A4A4729B9B69 D3D2A2DFDCB3B0AE88D8DCB7E4F0CC617753A2C09CA0C2A198BD9EBCDEC388A68E4B604D23301F 1212060C02001201001B08011B0A02190B021A0C031A0C031A0C031A0C031A0C031A0C03190B02 190B02190B02190B02190B02190B02190B02190B02180A01180A01180A01180A01180A01180A01 180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01 180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01 170900170900170900160900160900140A00130B00130B00150D02120A00130900170A01170A01 190B0223150C3123182C2314463D2C4B3E2E523F30361A0C350C00340000510700953817C85E37 D66136FF885ADA5B2EBF4015BF401762435575566878576C7C5B708F6C84946D888C647F916682 A4779696688580526E95657FA1718BCD9DB5C696ACAD8698D9C3CFECE1E7FBF0F6FDF4F9FFFCFF FFFDFFFFFCFCFFFEFBFFFAF8FFFBFAFAEEEEE6D7DADDCACEE2CDD2C5AEB6BB9DA5C9A6AD9C747D 6F4A525F394455313B492831432229412227513335593B39583B334B2F2341261540251041250D 4623005F2A00AB7016EBB548F3C148DEB132D1A52AA67A0FFCD071FFDE87FCD079F9CE72A77B1C A5761AFBCB76ECB86F86540DA4762B9D7329C8A05B2B03009D75419F7A4E3C1A00492A0BA7896F 694D353E220C3014006F553A5E4527371C00442B0C593F24462C135B43293C240A2C1600523E25 624E35635238301E062D1D042B19012919002A18022A1802291701271500271602261702261704 231605251506251508241407241309210F05200E04210D04230F042812052A1305291204271002 241102231103241204241204241204251305251305251305231103241204251305251305251305 251305241204231103241206241206241206241206241206241206241206241206221004221004 221004221004221004221004221004221004220E03220E03241005230F041F0D03210F052F1C15 3F2C251C0B04776561E0CECC1E0F0C1E0E0E4A3A3ADBCBCB998A871F0E0725140A1B0B00201000 2414042313042C1C0F2211091000009C898B8471750D000024120E2A1911231304251404231002 220F01210E00200D00200D00210E00210E00210E00251204210E001D0A001E0B00241103281507 2310021B0800200E021F0E041F0E041F0E041F0E041F0E041F0E041F0E041F0E041F0E041D0C02 1C0B01200F0525140A2312081D0C021B0A001A09001C0E03221407251808281B0A2E220C352B10 382F122B22015F57326661374A46175F5B2B6F6C39646030D3CCA2EFEAC4C9C9A3B3BB96CDDDB9 AFC7A5BAD7B89FBDA14D6950314A341F301E2931223C3A2E3E342A35241C2C19121C0B031A0C03 1A0C031A0C031A0C031A0C031A0C03190B02190B02190B02190B02190B02190B02190B02190B02 190B02180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01 180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01180A01 180A01180A01180A01180A01180A01180A01180A01170900170900170900160900160900140A00 140A00130B00150B01130900140A00160C02170A01170A0121130A2C20142A2414292613362F1F 4F423267514395746393634D6D2D126314007C20009E370ED76A41D2653C851800982C06744E63 7F596E8F677FA37991B78BA6C193AFBB8DA9B584A1A06D8C8B597699678285556D9C6C82B18296 EFC0D4EFCBD9E5D1DAF7ECF0FFF9FCFFF9FBFFFEFFFFFEFFFEFDFBFFFFFDFFFBFAFFFDFDF1E7E8 E6DADEF9E8EED9C6CCC3ACB4C3A8AFBF9CA3E4BCC4AA828A623D446C474E67444A4C292D573536 502E2D4F302B4F31274B2E2046291743271144260C4B2600602A00B47816E7B03CFFD558E8BB3A CBA226A67D13FFDE7FFFE08BFFD984E6BD657E5300D7AA4FFFE18EA36D25774200B1823AC69C52 3A1100734C11D0AB77654218371500907154795B43391D073115003015004A30173B2106351C00 341B007B6148493119371F073820082E180027110047311A6E5A42321E062E1C042D18032A1802 2C17022C17022B1603281602271602271602271604261606261505261406261408251307241005 2410052610052911052A13052C1203290F00270D00271103251203251203261304261304261304 271405271405251203251203261304271405271405261304251203251203261305261305261305 261305261305261305261305261305241103241103241103241103241103241103241103241103 251204241103230F04220E03200C0325110834211A44312A15020065544DE2D0CC261410210F0D 402E2CB9A9A9AD9E9B170600271509200E00200F00231202281707301E121F0C05261211D0BCBD 917D7F210D0E28151128150E200E001D0C00241102250F01250F01240E00240E00250F01261002 261002291305230D00210B00250F01291305271103230D001F0C00210F03210F03210F03210F03 210F03210F03210F03210F03251307210F031C0A001D0B002715092E1C1029170B1F0D012B1B0E 2D1D1033231638281B39291A3A2A1A423320493D255F533964593B807653857D56716A3E5A5424 5852207B734290875CE9E2B8C8C49EDDE1BCD4DEBBADBC9BACC0A4ACC3A9BDD3BCA5B6A3879483 6F7365534F43352B2123120A1B0900200F05200F051F0E041F0E041E0D031D0C021D0C021D0C02 1C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011B0A001B0A001B0A001B0A001B0A00 1B0A001B0A001B0A001B0A001B0A001B0A001B0A001B0A001B0A001B0A001B0A001B0A001B0A00 1B0A001B0A001B0A001B0A001B0A001B0A001B0A001B0A001B0A001B0A001B0A001B0A001B0A00 190B00180A00170B00170B00170B00170B00170B00170B00150B00160A00160A00170B00190D01 190B00180A001E100525190D2620103F3C294F4939574E3F7765577257467F5946A8745CA86749 9D512F86310C812702CA704D9138168F39187F5269885B72A1718BB888A2C492AFD19CBAD8A3C1 D29DBBB881A09A6581895770BA899FA7788CC79BACD0A4B5DCBBC6EAD7DDFAF1F4FFFBFDFEFAFB FFFDFEFEFEFEFBFBFBFDFDFBF6F6F6FFFEFFF6EDF0EDE2E6F9EAEFCDBCC2D5C0C7D2B7BEEBC8CE 9E777CAF878FD2ABB0886468502C2E66424477545255322E4C2B2247251945261444251041230B 4325094F2800713700C1811FE9B03DFFD95CF1C644B99117B08920FFE68BFFDA87FFDB88CFA74F 986F13FFD77CECBA65885208A9732DDAAC614C22007C5313B9925986602F704D254623055C3C23 2D0E00331604371C09412613270D003E2409442B0D4E35176C543A7860482109002A1200331D05 351F071C0600432D16321C05301A032E18032D17022D17022E18032D16042A1502291703291703 2816022815042815042714052913062913062911052A12062D12072B1104290F002A0F002C1100 2D1302281302261304261304261304271405271405271405281506261304261304271405271405 271405271405261304261304271406271406271406271406271406271406271406271406251204 251204251204251204251204251204251204251204261305241103241005230F04220E05261209 321F18412E2724110B87746EECDAD6311F1B23110F291715A09090AB999711000028160A231103 1F0E002211002B1A0A3220141B0801503C3BEBD7D8705C5E210D0E220F0B221006221101271403 240E00261002281204291305291305281204281204291305240E00240E002913052C1608271103 210B00240E002D1709231002221004221004221004221004221004221004221004261408221004 1D0B001E0C002614082D1B0F28160A1F0D011606001808001B0B001D0D00190900190900221300 2E1F0A564A306257397A6F4F8C835CA89F74CCC496D4CC9BC7BF8ED1C699BAB186E0DBB3CACAA4 D0D4B198A182707D6356644D2D3A262A35242B31232C2C2028221621140B211006251309241309 241309231208221107211006200F051F0E041F0E041D0C021D0C021D0C021D0C021D0C021D0C02 1D0C021D0C021C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B01 1C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B01 1C0B011C0B011C0B011C0B011C0B011C0B011C0B011A0C01180C00180C00180C00180C00180C00 180C00180C00180C00170900180A001A0C011A0C01190B00190B001D0C021E1204332C1A060100 100900140A0011010013000053322171442F4A1200632405843D1DAB6241F7AE8E7F3A1D450300 88526A935D75AD7590BE86A1C388A6CF94B2E3A8C6ECB1CFD29AB798627C97637A95667AC296A7 C298A6E9C0CEE2C3CBE7D7DAF9F0F1FFFAFCFCF8F9FDFDFDFDFFFEFAFCFBFDFFFEF9FAFCF8F8FA F9F3F7F4EBF0F1E4EBDECDD5F9E4EDDBC2C8B191969B7779A17D818B6769644042866262956F6E 4C2623542F2949271D45211343220F44240D43230A45260A5228007B3F00BF7D1FE7AB3BFDC94F F0C447A07902C59F3AFFE48AF3D07EFFDE8AC09B40D2AA4AFFE281B281259B6412CD984C815308 7E540CAE85459B743B916B3E4C29034523072808003C1D0B3C1F0F290E00402514371E083A2208 482E13795F44382006766048351D053018003219033D240E270E00321903341B073219052F1602 2F16023016053016052F15042C15032C16012B16012B16012A15022B14042B14062C12052C1205 2B0F032D11032E12042B1000270C00280C002E1200321704281302271405271405271405281506 281506281506281506271405271405281506281506281506281506271405271405271406271406 271406271406271406271406271406271406251204251204251204251204251204251204251204 2512042812052711042812052812052410052511062D191037231C46332DCAB7B1F1DFDB35231F 2412101B0907AE9C9AB09E9A0E000029170B2614062110002211002C1B0B3220121A0700A99594 FEEAEB3E2A2C13000025120C29170D2615052613022510002912022C15052D16062A1303281101 271000271000220B00220B00250E00281101271000250E002912022E180A251204241206241206 241206241206241206241206241206221004241206221004200E022210042513072412061F0D01 2513052513052816082917092715072917093525154334213F301973654A736548817451B4A880 A59A6D867E4FA1996ABCB4858C8456C9C49AB4B08AC5C5A3C9CCAF9CA089909380303322191B0D 070500080400190F0523160D2312081D0D00241309231208221107221107200F05200F051F0E04 1E0D031D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C021C0B011C0B011C0B011C0B01 1C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B01 1C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B011C0B01 1C0B011A0C01180C00160C00180C00180C00190B00190B00190B00190B001908001C0B011D0C02 1C0B011C0B011C0B011D0B011C0C000C00002114042416091A0C0147352B361E122202001D0000 300000430D004108005920039F674E612F18320300935771A0647EB27390BD7E9BC584A4CE8DAD E2A3C2F6B9D8FFC9E5F9C1DABC889E9D6E807B515FAB838EC39DA8E1C3CBE4D5D8F6F0F0FEFAFB FBF9FAFEFEFEFCFFFFFAFEFFFCFFFFFCFFFFF1F2F4F5F0F4F6EDF2F3E6EDFBEAF2FFEEF7D5BCC2 AC8D92C4A2A39270716D4949906C6C8764625B35325A352F49241B4925194925154926124B2812 4A2B0F492A0D502600834401C07A24E3A63CF8C34FECC0479A7200E1BD5CFEDC83EDCD7AFFDF8A C29F41F1CB66F0C55D9E6E0AB68026C38F3C835508936B25B2894B926B34552E033E1A003F1D02 3F200B3A1D0D381C0E2E12043116054E351F2A1200452B10735B3F291400402A123D250D371F07 2E15002F1600452A15290E003419063217043114023015023215053116053116052E15012F1600 2E15002E15012E15012E13022E12042F12042F12043616093717083818093518063415012F1300 2B0F00280D002A1301271405281506281506281506291607291607291607271405281506291607 291607291607291607281506271405281507281507281507281507281507281507281507281507 2613052613052613052613052613052613052613052613052711042711042913062B1508261207 24100528140B2F1B1255423BF3E0DAE1CFCB261410210F0D170503C0AEACBAA8A41000002A180C 2816082413032413012A1909311F111C0A00B3A09CE5D1D2281416210D0E301D1727150B231202 2310002813022C15052E17072C1505281101260F002710002A1303321B0B2D1606260F00230C00 2912022F18082D1606240E00261305251307251307251307251307251307251307251307200E02 2513072715092210041F0D01210F03221004221002251404241303231103241204221002241204 2D1D0D392A174839243123094335185C4F2D50441E7A6E44B9B183A79F707169386F6939C4C093 C9C69D625E3B736F527977625E5B4A6663544D473B2D241B190F06170A011C0E03201003201003 200F05200F051F0E041F0E041E0D031D0C021D0C021D0C021E0D031E0D031E0D031E0D031E0D03 1E0D031E0D031E0D031D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C02 1D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C02 1D0C021D0C021D0C021D0C021D0C021D0C021D0C021D0C021B0D02190D01170D01190D01190D01 1A0C011A0C011C0B011C0B011A09001E0C021F0D031D0B011E0A011F0D031F0B021C0800281205 170100241005200C031100001500003414092F0900471C0B70412D5D2D16340600340B00310C00 260600A4627EAE6C88B06B88B87390CC87A6D08BAAD390B1E8A7C7EDB1CDEBB1CAC894AA956678 B68C9AC49EA9D3B2B9D3B8BDDFD3D5F3EDEDFDF9FAF9F9F9FDFEFFFCFFFFF8FDFFFBFFFFFBFFFF F3F7FAF4F2F7F4EDF4F2E7EFFAEAF4D9C5CEBEA7ADC6A9ADB39394A687859E7C7B825E5E603D3B 58332D5D38304D271C532D20522D1B4A271149270E4F2D124F2D115328008A480BC98232E2A441 FFCF62E7BA47A47E11F6D473EECE77FADB89F3D57FD2B24FEDC85EC09628B18216C48E2CC38D35 AB7D2FC29A549D74364720003F1A003917003917003D1E0A2D10023B1F1340241843291A553C28 301800452D13543C203621062711002C1600371F072F16003015004023112A0D00351806331604 3313043114043414053316063215053015023015003016002F14002F14013013032F1202311102 3111023918093A190A41200F4E2F1B5B3B2656382045270F3117002B14022A15042A15042B1605 2B16052B16052C17062C17062A15042A15042B16052C17062C17062B16052A15042A15042B1507 2B15072B15072B15072B15072B15072B15072B1507291305291305291305291305291305291305 2913052913052913062711042913062B150827130824100527130A2D19104B3831F1DED8CCB9B5 18050122100C1A0804B9A7A5B19F9B1502002B170C291608281506271403291605301D0F200C03 76615EA690921500022610122F1A15230F062916072D1A092A15042C15052D16062B14042A1303 2E17073720103F2818513A2A563F2F4C3525361F0F2C15052F18082D1606230D00271406271308 271308271308271308271308271308271308220E032814092A160B261207230F04251106281409 2714062A1909271604251404251404231103210F012313032A1B080D000034250E3D2F14554828 8E8460C5BC93AFA7794A4213726C3A524F1CE2DEAFCAC59D8E88663932166D65522F2617110700 1C0F0623160E22150D1E10071D0C021F0F022313061F0E041F0E041F0E041F0E041F0E041F0E04 1F0E041F0E041F0E041F0E041F0E041F0E041F0E041F0E041F0E041F0E041E0D031E0D031E0D03 1E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D03 1E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D03 1E0D031E0D031C0E03180E02170F02180E021A0E021B0D021B0D021D0C021E0C021D0B01210D04 210D041E0A01200901220E05230C04200800220600280A002003002E130C391D19371A16391811 5B362D754B3D461B0A2700002500002F0F00240A00190500AF6D89B4728EA96481B06B8AD08BAA CE8BACC07FA1CF90AFE0A4C0E4ACC5B9859BA97A8AC59BA7D5B0B7D1AEB2E7CDCEDCD0D0EFEBEA FBF7F6F7F7F7FBFDFCFAFEFFF5FBFBF7FDFDF0F4F7FCFDFFF9F7FAF4EEF2EDE0E7E5D4DAA48F96 AD9498987C79A78A849677746C4D4B5634355632325D3736603B355A3429603B2B58332047230B 421E044D2A0E543115572A038E490ED18839E1A340FFDE6FDCB33FAA881AF8DA7ADBBC69FFEC9F E5C572E1BD5DE2BC51A07504C79929C49128D5A448AF853DA88146330B004C28004724003E1D00 45250C341500422513351A09240900573D2C482F19321A02301800361E042F17003C260E261000 3F270F3017013E230E250A00432614351806331604311404311404321505331606321505301502 3015003016002F16002F1401321301341100390E003B0E00340700340D00422102624525806547 84694C6F4F365435202D13022A15042B16052B16052B16052C17042C17062C17042A15042B1603 2B16052C17062C17062B16052B16052A15042B15072B15072B15072B15072B15072B15072B1507 2B15072913052913052913052913052913052913052913052913052A14072812052812052A1407 29130825110629150C2F1B123F2B24E3D0C9C4B1AB1704002D1A16210F0BA99795A3908C1B0300 2E180D2B15072A18042917032714032E1C10220F089A8783B19D9C1F0A0728140D321B132C1609 321A0E2912042D13022D14002B15002B14022E160A3A211A4D32295B3F3172543C88694A836445 593A1D331400290E002E15012D1604291305271406291306271406271406271406271406271406 2411032715072917092715072715072B190B2C1A0E2A180A291909251805261908291C0B2A1D0D 271A0A261908291C0B2B1C092E1F0A37281184765CA7997C6D60404B3E1C494019564F2550491F C4BC95B8B08CAEA5883B2F172B1E0D594C3C2616092312081F0E061D0C02210F0526140828160A 2715092410052410052311052311052311052212052313062313061F0F021F0F021F0F02200E02 200E04200E02210D04200E041F0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D03 1E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031E0D031F0D031F0D01 1F0D011F0D011F0D011F0D011F0D011F0D011F0D011F0D001F0D001E0E011B0D001A0E021A0E02 1A0E021B0D021B0D021D0C021D0C021E0C02210F03210D021F0900200A00270F03260E02230800 3113095D3F356F5147684A403D1F15492B214F2D215531232A05002100003A16062B0B00230900 1D090026180D9D5D77A0607BA3647FA56683A66688A56889A76A8CA86C8EC289A9B37E98814D63 5D2E3E8B6069DAB1B5FFD7D8F5D7D5E5D7D4EEEAE7E8E4E1FFFFFDF9FBF8FBFDFCF5F9F8F7F9F8 F5F5F7FFFDFEF7F1F1EDE3E4E5D5D6CEBABBCAB4B6E7CECAD2B6A8A6897981635B7556547E5B61 8B686F8762697851527751486944325A351B512C0F4C270A4B260B4E290F5C2C08884207E39B47 E3AA3FFFD960DBBE40C1AB34F2DB7BF4D988FFECA5E0B96EEFC169B2821CCE9F2DA07100B58519 F1C56CAA854E55330D3C1A004C2B083E1F003B1C00412307331500371B033F230D361A046E543D 3E240D4D331A2B11003B23093B230B2D15003018005D452D2E1600361E062F1600391E09331803 3318033318053318053318053318053318073219052B1300321C0431210A2D18053011003E1100 4E1000540F0087481DA16E39B09057543F08887847C3AD867B573F4C27152B0E002A13032A1301 351E0C35200D2C17022917032513002A18042A18022A18042B19052B19052B19052E19062E1908 2E17092E17092D16082D16082D16082C15072C15072C15072B14062B14062B14062B14062B1406 2B14062B14062B14062B14062A13052912042912042A12062C16092F190E311B10351E16B19D96 B49F9A210C07281310220F0B8D7A76A893902408072C110A371D0C3521091F0D0031200C25140C 2B1917C4B2B0C0AFA81F0C002B16032A11004025142F11092F0E05391A053419003019002D1700 2A121032141C49262C613B307A50269F7336A37537B2854EBA8F6D522E16260B00311B032C1601 2A15022B14022914012914012914012815042815042B1A0A2A1A0A2C1C0C3020102B1E0D281B0A 2F22123A2F1D2E2611231D07312B153D37212E2714261E0B2A2110271B0B1C0F003427176A5A4B 5C4C3D3828194D3C2C27160642311F40311A211500A79B83C2B69E7C705A60513E150500281808 2C1A0C3D2B1D2A180A1B09002C190B2A17091E0B002B15073A2013270D0030190B2A14061D0A00 1706003121121F12021D1000201001221002241103261005270F03280D04260E04220E03210F03 210F03210F03210F03210F03210F03210F03200E02200E02200E02200E02200E02200E02200E02 200E02200E04200E04200E02200E02210D02210E00210E00210E00231001200D00210C00230E00 271201281300251000210C002B15081804001907002414071D0F021507001A0E0022190A1F1305 1205004A3A2A6A574617000020060033180533180762453D51362D391D112205002D0E007B5B42 94745B3A18002100003C1B082708001F03002009001A0700251506965A739559729258718F5470 8C51718A51728C53748D5676AC7795A3718A926176936572B78A91DCB2B4F2C8C9FBD9D7E4D5D2 E4DFDBD8D3D0F4F3EFF6F5F3FFFFFDFFFFFFFDFDFDF6F4F5FBF7F6EAE2E0E1D6D4F0DEDEE8D3D2 D2BAB8D0B5AEB19681A98D779A7C719D7E7C9D7A818F6B7786616979555756312856311E512C11 4925054B2405512A0D522A115725028B4507DD963EE9B346FFE265E2CB4BCDBC46F2DF80FDE494 FED993DAAE65E0AE55AF7B15CB992AA97A08D5A63ED2A8565B390B3B1C003E1F0248290C3B1D01 3B1D0145270B3E200434190043280D4428105A3E264F351C533920381E05311700361E06311901 3D250D6951393921093921092E1500351C06321903321903321905321905321905321905321807 321903311C002C18002516012312022D0D004616007732139E5125C77F45E5AC69FFEDA8EDDB9B D7C793E8D5AB512C112D07003617052C1203240A00260F002C15032E1803331D08311C072D1803 2D18032E19042E19042F1A072F1A072F1A073019072E17072E17092E17092E17092D16082D1608 2C15072C15072B14062B14062B14062B14062B14062B14062B14062B14062B14062A13052A1305 2A13052B13072D15092E180D2F190E200901887169C6B2AB1F0A052813102B1613A3908CAB9391 1F010032150D3015002E19002A19002F200B27160F584848FFF6F7A7968F1E0C003E28102F1500 331400310E083B16102E0E00311400341B00331D062E1413301117431C1F582D1C9E6F37A67227 B68135C18E4DA5754D4A22083517002A12002F16002D17022C16012C16012B16012C17022B1905 2B19053A29172A1B08221300281B08342716372C1A3429172F27142A250F26240D332E183B3620 37321E342D1A352C1B3327173124142D1D102D1D101E0C0258463C2E1A111D0900463227372517 2E1E0EA79787B1A1916353434737271E0D002817072B18093C291A2E1B0C200D002F190B2B1507 1F09002A1303280E00250B002208002811012A17061F0E00291A071C0F00201000201000221101 231002270F03280D02280D02280D02220E03210F03210F03210F03210F03210F03210F03210F03 200E02200E02200E02200E02200E02200E02200E02200E02200E04200E02210D02210D02210E00 210E00230D00230D00200B00220D002710002B14022C15032A1400261000230C001C0200250D01 311B0E2A180C1E0E011F11041E1506130A001C1302190E0040311E89776348321D2B1100301100 3417052409002308002D1201270B008366488F70519A79582807003D1B02180000280B00220800 2B1406301D0E0E0000955E73915A6F8952698149627A425F77405F7A43627D4866915C78A6758B C291A4E0B2BFFBCED5FFD4D7FFD3D2FFDEDAF5E2DEECE3DEDAD0CEEEE9E5F5F0EDFCF8F5FEFDFB FCF8F7F2EEEDFEF8F8F6ECEBEDDFDEEAD8D8D1BCBBBAA2A0C1A69FC1A691C3A992A18378997A77 957278825F668B666D866262734E45714E3A644125512E0E4A26064F2A0D522A11562400843F00 CA852AEBB74AFFE46CEBD359E3D161F6E385FFF5A2F3D285E6BD6BCA9C3CBD8C23C49426C3942A DFB054A67C343614003F2003492A0D4526093F20034122054224083D1F03391E033E2308482D12 492E13684E354F351C3C2209311700351D03361E04442C12674F353C240C3820082E1600351D05 331A04331A04331A06331A06331A06331A06331A06331B03311D002C19002A1B08311D1437160F 4A1B09803E1BB56C37CE8946FFCB84FFE0A1F4DEA5FDE8BBF1D9B3C7A381643F222E0F00311708 381E0F361B0A2F14032D12012F1401321704321704321704321704321704321905321905321905 311A082F18082F18082F18082E17072E17072E17072D16062D16062C15052C15052C15052C1505 2C15052C15052C15052C15052C12032D13042D13062D13062C14082D15092C160B2C160B240D05 806961EAD6CF27130C2C17122D1813B29D9AA088842104003C20142D13002914003221052A1B08 1F0D09746465FFF9FD6855511401003E290E3117003314003F1D134621193B17093B1B063A1E06 371E08341A0D3C1E1355301D6E43208B5B1DB38236986419956326CDA0797C543B2F1000391F0E 3017033017012E18032E18032D18032E19042D1B072E1C083827132B1C072617042F220F3E311E 4033203629162B200C26200A2F2A14322C16342E183D35203F3420372C1A3629182B1E0D2E1E0F 200E00331F142A160B1E0800321C114B3528281707362616A08F7F9F8E7E5342322E1D0D2A1708 271405210E00321F102D1709240E002D17092812041F09002A1504240F003B2611200B00221000 311F0B251400221100211200231200221100221100231001231001250F01250F01250F01231002 231002231002231002231002231002231002231002220F01220F01220F01220F01220F01220F01 220F01220F01210F03210F03210F03210F01220F01220F01220F00220F002712012A15042A1504 240F001E07001E0700271000301907341A0D321B0D1701001401002F1D0F221505120600291D0D 1B0F0020130228170595806B7D644E2B1100260800331400280C002B10051B0000391D05886B4D AD8F6D654423391800310F00311100321203270B001200001E0B0031200E83505F7F4C5D774457 6E3A5067334A66314B6836516B39526B3A50926176B48595CEA0ABECBFC6FCCFD2F8CCCBEDC7C4 FDE5E1F8E9E6EBDCD9F4E9E7F5EBE9F2EAE8F9F3F3F8F2F2F6EDEEFEF6F4FEF2F2FBEDECEBD9D7 BDA8A5A78F8DBEA59EA78E78B79D868E716380615C7D5B5C69464A644044492624512D214D2A16 49260A4724044A2606512D0D5A321865360C8B4802C48126F3C055FFE575EED767F0DF77F2E187 FFF9A4DCBC69E5BE63B4881FD0A032D3A337ECBC5ACE9F4F986C2F4421004F301347280B3C1D00 44250846270A3B1D01391B0041260B351A003C2106462B1072583F40260D3016003F250C3A2007 371F053B230951391F331B03351D05311901392109341B05341B05341B07341B07341B07341B07 341B07341C00301A002E1C0032211136211C3D1B1950201283441BB16B2FDD9950FFCF85FBD396 FEDFB0FFFCD4FFF4CFFFDFB8704A262D0E002F13053B1F1136190B3616073A1A0B321100300F00 3713033514033615043516043417053318053318053219053218073019093019093019092F1808 2F18082E17072E17072D16062D16062D16062D16062D16062D16062D16062D16062D13042D1304 2E14072F15082D15092D15092C140A2B150A230C049A837BEEDAD32B1710321D18321D18BFAAA7 AE97912508003D2211311700301B0038270B31200E22100C6F5C60F2DFE346332F2A1504382308 351C003A1C023E1D0E3712093F190E3B17093415033014002F1300361700432000502700714200 A6742BBE8947AE7B42AD80596D452C3F1E0F34180C3217043118023017032F19042F1904301B06 311C09301E0A2715012D1C0839281640311E41321F392C193124112D200D251A06352D182F2712 28200B392E1A3A2D1A2E1F0C2C1D0A231200261503241102432D1F1903002B140640291B473123 1F0E003323138776668F7E6E5D4C3C2413033522132714051D0A002A17082B15072711032D1709 2B15072A14063621103826106D5D4445331D2513002B1903271500210F002B1905281300261400 251201241100231000231000221101221101241102241103241103241103241103241103241103 241103231002231002231002231002231002231002231002231002221002221002221002221002 231002231002231001231001251000240F00331E0D564130755E4C6F5846442D1B1B0400170000 2B1102321B0B2812042211012515052215051C0F001E110028190617050077624D9F876F2B0F00 2A0A003213002E12043216082E12005F4127967758B897762603003F1C00330F003919041A0000 35190B40291B1704001C0B005E333D5C313B582C3954283753243654253758293D5C2D417C4D5F 8A5B6B926471A3757FCC9DA3EEC0C2F9CBCBF7CFCDF5D7D5FCE4E2FCE4E2FEEAE9F8E8E8EADCDB FAEEEEFDF3F2FFF5F4FEF2F2F3E5E5F6E6E6FFEEECE4CFCCC1A9A7BDA59BB9A08CBEA48D8C7062 6548405B3C3A60413F704E4D5B3A336645365B3B245A381C603F1E5F3D1A5330104D2909592A00 9B5D10CF9031FDCC66FFE680EED674F3E384ECDA84FFF19AE4C76BE5C25CBD9323CC9E2EEBBB55 D5A5508858186E42134925014D2C0D3C1D0037180047280B432407371A004225074022063A1C00 34190042270A5E43283B20052C1100442A0F3B2106361C013218003E2409331900381E05351B02 391F06351B04351B04351A05351A05351A05351A05351A05341D00311C00311E002C190A281010 3614156234279D6236C68543E6A757DAA154F8CB92FFF4C7FFF4D0FFF9D6A783534722003C1E04 2E13023114042606003312034E281B421A0E3D15093E14063C15063C17073B17073A1906391A06 371B06361B08341A09341A09331908331908321807321807321807321807311706311706311706 3117063117063117063117063117062E14032F15043016073016073016092E17092E160A2D1509 3B251ADBC5BAE2CBC32D160E301C15230F08A9948FAE978F260A00351B04351C003A26033C290B 3D2B172C181759444BCBB6BD362120392210361E02442A094326063D1D06411C0C4018103E180F 3F1B0D44240B4A2D05482A003B1A00300A006233008F5E1CA57137885424875A33633920401C10 331209331805321801321702311802321903311B04321C07311C072412002F1F083C2B173E2F1A 392A15342510332411342512271A07372A1730240E281C063728133627122817032615012F1D09 2B16032E1906140000412B163A210D361D093E27152714032817075D4C3C726151725F50241102 3A27182F1C0D2812042E180A2F180A2D16082F180A2F180A341D0F3E291843341D9082677D6D54 311F072511002B1500280F003219052F14012D14002A1301271200241200231200221300221300 241102261002261002261002261002261002261002261002271103271103271103271103271103 2711032711032512032413032413032413032413032413032413032512032512032411021D0A00 1B0600261100432E1D6853428871619A8371644A39230900240A003821111D0A00241301362616 190A002415022F1E0A200C00523C24B89E853D22073819003313003013012409003E220A55381A C6A5847D5B383513003C19003713002603007858496E52441D06002411022D1C0A542D32542D32 542C34542C34552B35592F3B5E34426337467549566D3F4A6B3D478C5F64BD8F91D6A8A8E0B3B0 EDC1BEFCD6D5FFE2DFFFE6E4FFE5E4FAE2E2E3CFD0F6E6E6F9EBEAFCEEEEFFFAF9FEEEEEF9E7E5 FFF2EEF7E2DDD2BAB6BFA79DB29985BBA08BC4A998B0948896777291726D8867606F4F445F3E2D 4E2E15452405492807512F0C53310E563210623605905604CD912FF6C868FFDF83E9D37DF6E593 F0DF8DFDE992F2D673DEBC4ECBA22CBE911EF8C8669565194C1C00481B004521014A290A432405 4324054A2B0C3C1D00361700492C0E36180044260A3A1F02371C0040250A40250A351A003C2106 381E03361C01321800391F043B21083D230A361C03351B02361C05361C05361B06361B06361B06 361B06361B06361D00311D00342100301B0A2A100F3E1A1A6C4033A36D41C38846CD9040CE9548 EFBE84F5CC9EFFDCB7FFF4CEBA94635732053A1B004225135C3D2B42211037120248201441150A 4B1F1444180B43190B411A0B401B093E1D0A3D1E0A3C200B3B200B351C08351B0A341A09341A09 341A09331908331908331908321807321807321807321807321807321807321807321807301605 30160530160731170831170A32180B31190D31190D553F34FFEFE4D0B9B12C150D321E171F0B04 99857EBEA89D2A0F00361B00361E003C260036210238230E27120F4F383EC7AEB42F1715341B07 321900482C053B1E003716004C2810441A0C42180C451E0F58351774551F86651E815E0A734D00 6A3A00734009521E0033000075451D673C1A320B00361506361A05351B04341904331803331803 331A04331A06321C07341F0A33210B311F0B2E1D0931200C3526113827133625132E1D0B362513 35241032210D382612362410301B082E1904351F0A59432C745B453E250F250D003B210A412710 381F09341F0E2110003A29194E3B2C7F6C5D2613043623143D2719301A0C2D17092D16082D1608 2A13052912042F180A35200D37290F7D7254A292783E2A11270F003216002E0F00321100371603 3516043013012C1300271200241400211500241500251201271103271103271103271103271103 271103271103281204281204281204281204281204281204281204281204261304251402251404 2514022514042514022613042613042B1809352213392413281302150000190400392212593F2E A388757A5F4C3B200D2108002B160327150121100031200C2311002E1C042E1800382006C0A58A 6143273D1B003011003C1D08371B063315006E4F30C6A4813A18004C28042F0B00391500AC8975 9A7A6B3317092B14062E1B0A130200543230543230533130523031543034593539613941673E46 693E476B404775484D996C6FCC9E9EE8BBB8F2C2C0F8CBC8FBCFCCF6CECCF1CBCAE7C5C3ECCECC D7BDBCEBD6D5E8D6D4E9D7D7FDEEEBFFF6F4FFF4F2F6E3DFCBB6B1B49C98C5ADA3D6BCABAA8F7A BDA291AF9385896B60886A5F7D5D527A5A4B7C5B487050375C3B1C4C2B0853310C62401B633F1B 5D3400824C00CB9531F1C66AFFDE8DECD68DFCEBA5FBEB9EF5E48CE0C85ECFB03BB69015C79C29 E9BA60774707542302592C174B26094E2D0C4D2C0B4C2B0A4B2A093F20013B1C004526073A1D00 412406422507351800381D003E23063F2407351A00381D003C21043A1F02381D003F24093E2308 381D02361B00381C04381C04381C06381C06381C06381C06381C06371E00331E0036210037210C 3A1F16421F19582F1D7B4A21996126C0863DEEB46BFCC68AECBD89FFEDC3FFEAC0EDC7965B3609 3210004D2D187C59465934223A130243190B370B004B1D1044180B43190B411A09401D0A3D1E0A 3B1F093B210A3A220A361D09361D09351C08351C08341B07341B07341B07341B07331A06331A06 331A06331A06331A06331A06331A06331A06331805321704321706321706321809341A0B341D0F 351E10523A2EEBD3C7BBA59A230D023A231B341D15AB948CE8D1C32D1100422807371E00372000 3E2604361D072C130F81666BE5CBCE40251E391F063F26004B2F004829004F2E05522E0C4B2309 471D05471E085D3712876424AE8B37BC983ABA923D96652D4D19005521005420004F2000451A00 471E003D19013D1D06391D05381C06361C05351B04341C04341B05321C0538220B352109301B06 2A18022F1D073727103A281235230F35230F311F0B3924113F2A1738230E331E09351F0A321C05 321A026149318C72599E846B391F063C20084B3015341A03341F0C241100321F0E3823128D7867 2D18072D1807412A1A331C0C2A13032C12032F15062A1001280E002C12032A15022A1A004C3F1F A695793F270D2B0D003A1701380F00370C004217063F15053815023213002C1300271500251600 2717002813022912022912022912022912022912022912022912022A13032A13032A13032A1303 2A13032A13032A1303291403271403261501261503261501271403271501271403271403271201 210C002009002912023720103A23132F1808230900391D08A185709479643F2610321905301A05 1E09002B17002612002B1500341C022E1500B4977987684935140038170031110046260F3F2003 C1A07F9876513714003E18003D1900A581679E7B67371607250800412A1A220F001E0D0045271F 43251D40221A3E1F1A401E1C4422214D2929542D2E4920246137396C4041794D4CAC7F7CE4B7B2 FBCBC7FACAC6E7B7B3D6A9A6CA9E9BC39B99D8B6B4CDAFADE4CAC9DBC6C5D8C4C3DCC8C7F1DDDC FFF9F5F0DBD6A18A848F7671CAAFA6EFD4C3917661A68B78A489767D604E745745573826583724 402009512F145231124C2A07603E197F5C3675522A582F00895800DBA946FAD27DFFE9A1F2DEA1 FFEFB3FEF0A7ECDB83F2DC6DECCE54AD870CEDC353C99B4666370153230C572B1E502B104A2908 4322014120004625044B2A094526073E1F0048290A3619004023053A1D0043280A361B00402508 361B003B20034126093F21053318003B1D01371C01391B013B20053A1C04381C043A1C04381C06 3A1B06381C063A1B06381D003A2300331D00331B01371C093514033711005527037A4616B57A3E C38846C68C4CD19B5FE6B37EFFD3A29F7648421D003B1700411C025C361F3D1400380D00522716 3D12024116064016063E17063D18063B1B06381C06381E05371F05352005361D07361D09361D09 351C08351C08351C08341B07341B07331A06331A06331A06331A06331A06331A06331A06331A06 341906331805321704321706321807351B0C381E0F382113685044DCC4B8C1A99F1E0800321B13 2C150D988179DBC4B4280D004E320B381D003A1F00513810452A0F482B23D0B2B0DDBFBD381A0F 3B1E0052360664470F896B2FA584518C673A6942176740176A3F1C7A52219C762DBB963DC59E3F C09546A26F42521C004A1400612F0C8D5F2B70450E562B006B431F4220043E20083D1F07391D07 381C06361C05361C05351C062F16003620093A240F35200B331E0934220C36240E36210C3B2613 2F18063C2211462D19351C082E1500331A043117003A2007290E0042270CAF9479C2A78C42270A 3517003217002E18032C17063C2716321D0C978271331E0D240D003C2515351E0E2A13032F1506 361C0D3218092F15063218092D17022A1600261500A0886C3A1F042E0A003F14013E0F003D0C00 4A16084516063E13033712002F13002A14002A1600291701291200291202291202291202291202 2912022912022912022A13032A13032A13032A13032A13032A13032A13032A1301271501261501 2715012715012715012715002914012914012B16032F1806311A082D1604271000250E002B1100 3017032E1200240600593D257C6249492F18270F00341C04311901331B032E1600361D002F1400 A8896AA382613210004724043E1C003C1A00593817CDAB8656330B411B0048220097704FAE896F 401B08371607371A0C130000210F002D1D064024163C20123D211341251944261C43221B421F19 441F1959312F6B423E7A4E4B8A5E5BA37671B0837DBC8D87CC9B96DFACA8E8B5B1C1908CBC908D D2ACA9A78583DEC2BFEAD0CFE2CAC8D5C0BDA18C89C2ADA8E0C8C4F7DED9C7AEA9CDB2A9F8DDCC 6F533E8A6E59B99D874F301B61432B84644D6A4A3177553C4F2B1156331555310F3E1B00714B24 9B764C754D10835400E5B755F9D486FDE1A2F5E1AFFFFBC7FEF1ABEFDF87E2CC5DCFB338E2BE44 E4B9508254076436055A2B194A1E134D280D4C2A074B29064A2805472603462502452403422402 4224024223044023034023034023033F22043F22043F22043E21033E21033E1F023D20023D1E01 3C1E023D1E023C1E023C1C033B1D033C1C033B1D053C1C053B1D053C1C053B1D03331A00371E00 3B21003B1E00391A00421F01542B0F6736156F36097D4007854601AE722AE6AC6CECB982491E00 3C11004A1D00481B00481B00491B01481A03441702421704431A08401A073F1C083C1D083B1F09 382008362106342005331F04381F09391E09381D08381D08381D08371C07371C07371C07351A05 351A05351A05351A05351A05351A05351A05351A05321702351A05341904341906351A072F1504 3B2112563C2D604639CCB5A79B83772C14083822173D271CA28C81EED4C355381A5F3F165B3D0B 6347157C5F33533415684937FFF3EABC9A904727106142166A4C10826320D3B26B8E6C2DA07C3E 7C5919714B0D855C26744A0E997020AA8127AA7E25A0712B7C47255E26155A230F804B29B18347 B88C459A6D2C9166317A56343E1E053D1D0442240C331500341800381C04381E073F250E392109 361D07351F08331D062F1B03331F073B270F301703331A06371C09371C07351A05331902321801 32160033170036180035170041230762442876593B573A1C250A003E2511230C00351E0C220B00 8069574932202A1000321807321807321807321706321706321706311605311605311603371F05 2D150051331948260D3F15004515013904005C2415480E00461101744334370C003B1804321600 2B1000280F002C12012C12012C12012C12012C12012C12012C12012C12012B11002B11002B1100 2C12012C12012C12012D13022B14022C1704301E082B1601230E00261100271300291300331D08 261000301703280F003F2612280F00280F00391E095C422B2E10003D1F032F1100331800AF937B 5B3F27280C00331900351A002B1000381B003D1F0091704DBB99744826003B19003C19003A1700 AD8B66AB8860452000492200876039B38A6A5129103A150233120335180A2C1203240F00261400 3F26103F261042271442271441241447271A57352969443B6F49408F675F91665F865B548E615B 8C6057986961C19089B07B75C18A85A77470AC7C78BE9591A27F7BE4C5C2F2D6D3FFE7E3D3BBB7 9A827EA68F89EBD2CDFFF5F0FFECE5FFECE4B89B8D957664896A558D6F57B7997D5A3B1E47280B 603E22634024573217633E216A4322522C07512C027B5528A0783A835800D6AB4CF5D38BFFF6BF FFF2C8FFF2C5F3E8A6F8EA92CCB74AC9AC36EAC552815700673A005427005527175C32264E290C 4C2A054B29064A2805482704462502462504452403432503422402422304412404402303402303 4023033F22044021044021044021043F20033F20033E1F023E1F033E1F033D1D043D1D043D1D04 3D1D043D1D063D1D063D1D063C1E06361A043A1F043E22003C1F00381A003B1A00451F0851240D 4B1500682A00894600C48132F7B96EEFB77A5124004B1C005119005B1F005B2302572002501D02 4C1D034A2008462009401D073E1F0A3B210A3A220A382308372207352204352005382008391E09 391E09381D08381D08381D08371C07371C07351A05351A05351A05351A05351A05351A05351A05 351A05361B06381D08351A05361B06391E0B3419063C221153392A4D3324BEA497A89084291105 311B103721169F897EEAD0BF4625065330065E3F097C5D26957544624118745036FFF4E18C6852 3A16004E2E00513000664500C2A24FA58137B490469675249E7D2CCEA8618A6018A57823AA7C24 9364128553145B26067F4736A36C57B07C55BC8B49C08F40B3802FA777358B643D4B2910422007 43230A3919023E20083D1F07391D053E220C381E07371D06371E08351C06301A03331D063A240D 331803361A05391D08391D07371B053519033418003418003416003A1C023A1C02391B0044260A 5235174C2E12381D0239200A2A130138210F2A13017B6452553E2C2B1100331908321807331807 33180732170632170633160632150532150330140034160059371E441E07320500441100602819 A2685A682E206A3223935F5153251546200D3512003314003A1E092E13002D13022D13022D1302 2D13022D13022D13022D13022C12012C12012C12012D13022D13022D13022E14032E1501240E00 2A14002913002D17003A210B3820082C14002911006147304D331C2B1100361C033014003B1F07 41250D51361B4526092C0D003E1F023C1F01301100B5977B6143273C1E023516003A1B003D1C00 3514006E4C27CBA88258350D411E00532F0B391500BA976F8964383E1800754B21BE946EA87D5D A0765D643E29311000230600270D002E19062E1C06442A1141270E42260E4529134C2D18553622 6645347652428E685B744C407E534A92675E986C63A4786FA2736B7F4E4798615AB9807989544C BE8D86976C66C09B95EECDC8FFF2EEFFF8F3E4CBC6A78E89836A65C9B0ABE6CBC4DEC1BBB1948C 97776A553423A5857097785CAB8C6D6E4D2A5A38155C38185A35185D3619552E0F5D3414663F18 512A005E3605966F2EB68D31D8B154E2C380FFF0C0FFFDD9FEF2C8EFE4A6EEDF8CA8932ADDC251 DAB54B4F2600663A00532800552C1857311E4D2A0A4D2B054C2A054B29044A2803492702472603 462502462502442602432503432503422402422402412402412404422304442304442304432203 432203432203422004422004411F04411F04411F04411F04411F06411F06411F063F1F0A3B1B0C 3C1D083F21004021003B1E003A1C003A19084117094410006A2B009F5611E39845FFC274E6AA6B 502000521F045A1100712300772D0A652301541900501D004D21064420064121083D230A3D250B 3B260B3A250A3924093823063921073A20093B1F093A1E083A1E083A1E08391D07391D07391D07 371B05371B05371B05371B05371B05371B05371B05371B05381C06391D07361A04371B053B200B 371C093B200D4C31203F2516B3998AC3AC9E2E1709341C103E261AA68E82EDD2BF8360428F6A3E 9D7843B9955BBF9A6376501F764E2AFED5B5926A466F4716845F197E5A06856204D2AF51D1AB56 CEAA54BD9F3FC1A341EBC76F8E640EA5771F94640F6534005C28006E3816602A10673213956132 C6914BD8A24CD39A40C6924693693F532F154420064220053F1D0444240B3F1F06391B013D1F07 391D05391D05391F08371D06331B03351D05392109361A043A1B063C1D083C1D083A1B06381A02 381A02381A02381A023B1D033A1C02351700331500391B003F210740240C331805341A093C2211 321807715746664C3B2B1000331807341908351808341707341707341707351506351506351604 3616002E0C004420083B1200390C004B1A09582313834B3C632B1E4F1A0C6433253A0C00411707 361100300D002F10003114023015023015023015023015023015023015023015022F14012F1401 2F14013015023015023015023116033116033118043219032E1500371F07492F18452B12301600 250B004A2F1442270C351A003A1F02331500371A002E11003314003213003B1A004B2A0B4C2D0E 4B290D613F23C19F835736173817003A19003C1A003D190057340CCEA97F5F3A0E563105320C00 876238D5B084462000673E10BC9166D2A67FA87D5B552B123C1601330F00381809351B0A2F1A05 2816004A2F124025084022064C2E125B3D23624229603D275D382548211069423172483A784E40 8E625782564B7041397F4F458C564C8A51488852488F5F55926760A37C75FFDFD8FFECE6F4D9D2 D3BAB5AD948F8E726ECCB1AAFFE3DDF8DBD5B3958DC2A0947D594947240E89664AC4A27F805E38 54310B4D2703593213643B1F4F26084A1F00653B15673C115C32006C4502CDA64BE4C167E9CB8D FFEBC1FFFEDDFFFBD4F3E9ACD9CD7BA18D2AFADF789D791B623900673D03562C045E391E49250B 4E2C094D2B054D2B064C2A054B29044A2803482704482704472603472603452705442604442604 442604422503432503462506462506462506462506452405452405442206442206432106432106 43210643210643210843210843210841210C3D1D0E3D1E0A4020004322004124003F22023C1F11 3F1B0F53200B71310BA65816E79645FFB668D08F4F4A1800551C0171170098320C9D411C802E09 621C00591E00512204441F0243250940260B3D280D3D280D3F270D3E240B3E23083D22073C2008 3B1F093B1F093B1F093A1E083A1E083A1E083A1E08381C06381C06381C06381C06381C06381C06 381C06381C06371B05381C06341802361A043C210C381D08371C09432815402615B69C8DDDC3B6 341D0F3C2418472F23A99185E9CCBA411C005C3208754C169E7639B68E508E662B9C7242FFDBAE AB804DA67D3DBF9742C19B38BB962CE1BC52E8C061CDA949CBB047CEB348D4B34CAE8626C99A40 A67320652F005A2400632F0066320A774417925E25935B11975E07D79638FFCD7B84582B4F2B11 442006411D03401C0447250C3F1D043A1A013D1D063C1E063E20083C20083A1E08371D06371D06 391F08381C063C1D083E1F0A3E1F0A3C1E063A1C043A1C043B1D053E2008381A023618003A1C04 3D1F073C1E06391B03361A042E13003A200F391F0E331908614736745A49280D00331807361909 3518083518083518083616073616073616073716054020092D0B00330F00340E004118044C1F0C 3B0C003C0D004C1D0D3102003B0D002900004019083E1907381502341300331604321704321704 321704321704321704321704321704301502311603311603311603321704321704321704331805 2B0F002E12003418024F331D7A5C448F715792745A987A5E7A5B3E7253366C4D2E5B3D1B4C2B0A 4726033817003A19004221004E2D0A603F1C341300533010714E2E4E2B0DB995755D39193F1B00 3C18004822004F2A00B590646D481B936E415F3A0EA68053997344471F00B88E5EEEC396BD9268 5B300E390F00371100421E0E4121122B1100200B00271500492C0C45280848290A5435165E3F22 5D3B1F5331164D29115A341F5C3621784F3D794F3F582C1F5C30237B4F44835349915B4F854C41 814D40A8786C875C53B79188FFE0D7FFEBE3DFC2BCBCA19A987D76987D76A58882D5B6B1CCAEA6 A5847B926D649E79697B573F3C170076532DD6B187785329461F00542B0B663A1D663A1F592C0D 5A2E09663A0D6B400D6A4100A7822AE9C974FFF3BAFFF9D1FFFCDFFFFFDCFEF5BAC9BE6FCEB95C E5C86A653F00683D00592E00562C045E3C174D2D074E2C064F2C044F2C064E2B054C2A044C2A04 4B29044B2904492903492903462804462804462804452703452705452705482706492606492606 48250548250547240447240647240646230746230746230746230746220846220846220845220C 4122103F200B411E004220004123004025083E241541211451210B6322008D3B00CB732BE99650 B872364E1D00642504992B08C84A24CF5B36A9421F7E2A066C28055E29074D240447280B432A0C 422A0E41290D43280D44240B45230A4422093E20083C20083C20083C20083B1F073B1F073B1F07 3A1E063A1E063A1E063A1E063A1E063A1E063A1E063A1E063A1E06381C043A1E06361A02361A02 3E220C3C200A381D084025124D3221C6AC9BE5CBBC361C0D3D2618442D1F9A8375D4B7A5471D04 663912744912916828AE833EAA7F3BC89A5EFFDDA1C0904EBB8D3FD0A642DFB746DCB540EAC250 FAD168DBB550C4A93EECD565D1B142F2C960FFD074E3AF5CA970298B5413B27F3EAC7B399A6927 9D68249E641AB2711FD38C30BF7E2E6A3B0F482308472207421F03421E0447250A3F1D023F2004 3D1D043F21074123093E23083C20083A20073A20073A20073A1E063E20083F21093E20083C1E06 3B1D053B1D053C1E063D1E093718033519033D210B4226103D210B361A04341803311603402512 381D0A321704583D2A8166532B0E00381B09361907361907381907381907371806371806381706 37160340200B3818013D1A043916023815013B18043813003F1A083712002C0700381404310D00 3A16063511013716053F1E0D341803341803341803341803341803341803341803341803331702 3317023317023418033418033418033519043519043E1F0B3B1C083415003B1C074D2D1653331A 56371A62432481603F82613EA1815BA78760AF8D67A3825979582F65441B4422004321003A1800 82603D4E2A0865411F462202401900845D3C5A3410482200441D004821009C76498D6738D5AF80 866031C19968552D008A602EFFDEACAC8051491C004A1E004F230A3E1501361202331304290F00 2914002D1B034426044C2E0C5837165B3A195332134C2B0C522F135B381C845E478B654E613826 542B1984584B865A4D6F433887574B8F594D592114925E5186564A91675B7C564BEAC8BFCBADA3 D6B9B3A0857E886D66C7ACA5AC8D88BFA09BB4938CBB999069433A633C2D87614A7C583859330C 876236C7A0756A431A5B3010592D1063351B673A1B5D2F0B603407724410774F0AAC8631F3D481 FFFDC6FFF1CCFFF7D9FFFFDCFFFFC5B8AC60F4E087AD8F375E38006037005E32035C350A533209 54340B4F2E05502D054F2C064F2C064E2C064D2B054D2B064D2B064A2A044A2A04482A06482A06 4729054729054628064628064A27074A2707492606492606492606482505482507482507472408 47240847240847240847230947230947230946240B44251141230B431E01421E003F20013D2109 3B24143F221251210B5817007B2600B35714D47D3AA75F255524006C2C09B03813E35831E96B45 C1532E913510742B08632B085028054A290A452C0D442A0F442A0F46280E47250C48220B46220A 4020093D21093D21093C20083C20083C20083B1F073B1F073B1F073B1F073B1F073B1F073B1F07 3B1F073B1F073B1F073A1E063F230B3B1F073A1E0641250F3F230D3C210C432813604534E5CAB9 E3C9BA381E0F3F281A3E2719897264C4A7953C10005F2F09683B04805511A1752EBB8F46F0C07E FFEEAADAAA60C3953DCCA138D8AF39E0B83EEDC54CFFE377F6D167CFB547FFFF8FE1C24EFFDE72 F8C76AF7C06EDBA25BB6803ADDAC60D2A355BD8D41C38F43AD71289F5C0DBB7015A05B0D572600 4820064D280D4722074622084B270D401E0347250A3E1E0543230A43250B4022083C20083D2109 3C22093A20073D1F053E20063F21093E20083C1E063B1D053C1E063D1F073819043A1B063B1F09 3C200A391D08351904381C073E220D381D0A412613391E0B3217045A3F2C8D725F2E11003C1F0D 371A08371A08391A083819073819073819073817063817043616013919023D1D083B1B06361702 351601391A063F200C2E0F002708002809002A0B00341302341302351403331402361703341803 341803341803341803341803341803341803331702331702341803341803341803351904351904 3519043716033817043414003717003F1C063C1A00401E025231105D3A1A4826015A38124C2B02 634016815E3499774ABE9B71B7966D86643E64401C5A3612825E3C633F1D562F0E6A4322704825 744C28542D064720004821009670419C7647D7B18099714099713E623806FFD7A3DAAF7C502400 4D20004A1E003C10002F06002E0A00341405331908331E092D1B03 end %%PageTrailer %%Trailer %%EOF c++-annotations-12.5.0/celeb/celeb30.gif0000664000175000017500000011511014624367210016452 0ustar frankfrankGIF89a?              #+" ' 7$+$ + 24;7 #(7+ ':" )#7&.)*(&.0*'%7*'93*8(7:75)-2,&GEGVUkF&U)F(V'H4W6U5j0L&G('W)(G6)V8'G97W87N+5h((g6)g98x87t,,o#2G5D+pHIC;WG9VI,gG(gI8hU:wW9vK1gX+7)F3.J,BH9GO6Mn:HI;b;MEJGEWJGZRJYVUQLTgHGwHHgWIwXHgYVwXWnJVOkSxeIjcZwfYsnPXNfoVjjgexifzsjvouYqe..981/5/5!RoM3K1i1s2YQ.j4\,;E:JGGGHXXXXQNXXOPhIhXuXwYnMnSWiZghfhhviygyvxvivghhiwwwxnqSOpMrNwxnqchjo1͑3ӥ5XQxphytt͒OQԬQPˊvmѪonp]!N9@ $ ( U6b kʵׯ`dVԐ_  9͍nBJaĘe LpGg3 ۴2(#F 9$E(/¨SFmBĭB/dɃM5~զQaSܑ @ԁ CJ_Mu9>b:LY"@ P@G$،/WPtrIBځ]lp@0h @ii_]&QOE r2ҰHsN쒋cM;)GsXGT10dH(:AISFL) r$ H'L0BEMR"CmI)l8CX!M(\.a^;AG5,8)VeTA) pFH .@QܥiV@p fs 1(8Va9lTEVXcM8e>@sS l!JD7Q WmJe  t n0hE if@ZL5kAQ;GTss2ႋ/ZNe8Ts`@(U @%AtܫV@w,H+gM%#3M !CH(ydsB; ss!lXBp9XO2Z >mdKz@rN&'.)A Cҭ|a0 3<,U9: a$Tq ,LK :ChT`ё[,Y"9Ps b4Ո5@X>\5ܱ "8;܁L#Fhq[esL xc@``HAP dD t4`p(Hr0 9Pj?؀<ZFN@` /vюvAx98Q26> r  L "@zQ8%`\EIZX@(0 @<z̀ t 8Rvhwd %\ȇ%&^l :q#FG?z,2 /BK4+Ip H hʀ4aeߨ`P H yg1;@@ܱp\8@>"͞1 B@ vF P_%@p "  aF@iE\i 6"h(4`vCh&LT.Αt ȃRu2 z&J#PGа`K o;g(L# (\Bi@P]T0\wYȅꬁ|d"B r9=4FQcrD ˞#lׂ0C iHńfGZ$@& @{v\DjLnTQ+3grEtd@(2v Gq0›[! oB |!@ y5`fl( '`De 4Z#0=5`e( D" 5ð#bjw:8Y9tH 7?8[0Q٭@g$$+$ee kq]@`ep =ahzpXmEByFHgJ| 46tlP7@KQIgyPR=fNׁIZ 6)$s3i 0!] 9pːn\С=ؗB*L#Fo Rp8 )hf`ҁ/EPpܫT!/~,!a@8C dip Ns%Dz(扇=FKhA .7@ 8G4DB7U $t@(pLLr; Ї{[V҆+ VnPR0 ʨQ݀1zƨҁ 瘆x.V !|U`(@.1ul" Pn F 71 'Q13# 3#`BJQdU=cD (CUځC y  aF`mUe\ey1p(#g Ofyt ewr=ґ,v,f{Tm74kIg84Aw! ˲C(! x[|2@` `VlW#A.oRe(* #`!y g0 0p( 8  E!1#FTgqlgPy@icm `-gq9|:3{2Tm 9IUW( @oU^/  s>'? /3It(D!akn Hft1,!∹nXxϲq/1}w{##", fp)1#T 7/o#aluKЀ/FSszrnxqq$ s@KF-v5/occ N"I߈pP*x!/+.`w }@15X=5q9rPIP7begI/:2@ (0FH`l@@X ` Be0pj30@&1@_0HА#@Z#g`( D1ܑ“?y%P`@Un`-a-(().q@87@@'2-mCEnِ F `%R_YPYuKPM7 h@n, n0 8  vJ)0qe"ւ!ɟ=19AyzlOP I k^4%ħ(Ț% KP+A;h0 ЀIt 5F4֐ r ^H ЖF`/*Pg@0 h(#pU  gDUues(`m7I[1Hrj#3" @ ^. z#2RgV3YSAmEI59` 2W8GFJUpF"dX!Uj#*@:4^:;K`t"0p()n 0 z'ɬ9A$yxJ?)Ebp +I-` @ Mp$HDh ]{7da[NhJ{KlJW4P(@چqG@uQVPU0lx# `20 0p!lLQ #1^c[qѶg92 P=4D"Qj!g/P@ jJ  PA{f0_y%@ Jpy`Bu/@ :R0BX+pLx hBHPg z1 pj U0t0x[hi`2!1#wqh@aF+6u=A~.$=`(`I j&uJ j FWY D`oƆBx#0p1`@D|x7. FЂ#e0`0 tHF y@ avZ:#pgfJ"36!1\eV[',xf@J.7j D@B H yJ@@ yPFeH2 yx%p7 TW<0x` s rOtD\9o0UJm5#nn1g#@f($(td\fnyn4A3K813AG$ "B9o `!LjP[ {y`+*g$3)!pE`hT2Na>3P 6 Htlq) U@1VRy Ѐ s)0 t3e/ s R)prNz]\ <A~1I)d(@"$t@ Ign Q%{(Q3Cl*,@7آJ(B- @ OP=HEl`8Hs6t,tcPu[8"oVW] q'n &3tb `:3g 7@da J@h)$PR-?I!ig`+xI`fEbTi%.00 Cꂗ{y# z%A$kF-OЀ̍j(yRx#\5!(" K.q A$KbK0 X% E&MPOh`i~ >Onu> m)A UAV%@@сd}y73 -(@z n0 0ڦ.Pu< 1 zw50~.`YK'(@ H-5eU@&|\.{l5:` KM`)C M(Mb72~+ O65( @.IjPσ f`wBIU  SPAL&') 6 >S,N"y"hl H& B$ˊ VgF: `MEyw kSE0PJmO#kpd8H *as~$ 4XI?9Fa_JʷQp4h +D2n P p`t120m <"P[}f0 qJM@a K` . oaEÒdbP `PF`I  I`z+#@fI0#. hБ&&D@#F@!C\* fpfTi/FP 7p ŦJFTac䀆*oB$ ^aƍ#)F,iTyA ` řDÖ =$p0R*sQ^}X`€ p AH5XHPt\*ä%2$!#1& E(mAFh(5D@rD5 ,H́T8xҔ@@FH0k21I#q_y0Hs:sƚpb2n=hB뤨0*@GD@S7i`p@ D@#h؀0 \* ~2H!<,!ڒ@ rjd'( DQnHeJ9  x5 Dj<$!Pi0OĤ&(Y0 4fa( $$P`$ `0 7 U#+lEB sIirԩ2Q`*8@:I`3ej7_}L+ @6'@L  jIJWrd6d : `SXfXP*Րpb I xPp(H#fa4&L#B  l= "U$z#7@]lyЌ$ 90Esqs\:\xmhF91cόNt5&p |%0$$%tӋ(M2DICyG@9  p'|Ȃ*H%&H *5J6 I*,X#J 504 P,(W" p 2h @.a4`2ʐ`JA C HQbzHs\TFL p STjATSh3(PQ@wPT) »N?U@~T-Dy(|d:*VH d tI((jD$0q=!@ @{6 " pE*a5Xa)( S8eIDQI@ <',PS6 .b9 ʃ h:PC@Q B%A 3)J5Ё hX qp*B ^ /t4蠆9%n@=0@@  PP  { .@P vP&t(Xh"'@q$,r %p kPH'@h!`P)p0:.K87,W pD֐ ',o;x <$x^0$ML(A=p;70(!"pAO0IA&>юPС)F@A R`ȃ^3QI9(+ X\ؠm Q=4ԶH(xxCP O7U8 $H8BKщ5$(])!:DJ J@ƅ+" p¾KJ8>  #x'$W!! J@o4H$pmC *Am@p7| Tط'IԐ$0 )~ H A $ {H#s Z[2[[A"@P(NDA HA @! n#< &@56BW(uf@)|jWD7 H$'b+) Hbh%qPCe{%GJ RT r4>[:BIah71l8d6 ̰P !0[F!*I!@Ef4Tp*De x4FA0@"26A{2bN̔SXKI`PCqj, p$2S'Kx%[ 3΁ ,fЁ' (d p &36"J І2Ro, Rc@EfX8BBY  `$f8ܢX, B.9 "rC;$ِ  uG}_*ǗuF HA$2\ O7$ʇT,P7Y!é%1Jx0\+]JxJTb K( $(.o &-T2uppHrPoI@+P :7@8xz\p9p@7H"0 '8 ,jP0v؇`"< jқ(I'8-0&:qi01);9&ȀP@<&018HI(: IoCS8W82axW@xKhkGW0@WpufGHM&隄Qr)U')uJ`H؆z؆&ثo@;uj@z6:3*@Ѓss X`@ `8ѫ @ 3vh"{ #p0&vc"!Hk(W;"(&"o> S"hC ȣECH`J9qnpUpAxg8fW'hsxp0WhWn(IUD؂@J%(FZo0m((poPo3IH"CrřBP0h!Cr3@Ѓ3H7*[Y  kH!#oʃ&!!B(s ,B3@hB:a@I( YXoGp7TIp1?fxI uPUnJTfXGhOu0?Gns0Gxp|rOO0T&N.y?TSMGHnPzJPqPHoUHAP869x=Z*HAAh@7X Fʛys ڸ 9h3}X,Do PLlG p~ً8x3p(#ⰵex1/4mI`tT8OIR☄TnȳJpNc*$s@IOhɔtyfpnnIrSd'mnTaŏK7-?p`'u(GJH@u9i Rȃ+* +"QxTQi@7 ph(84* i @ȃjp ]։ȭ}Qe` T 3y)ڰO 8aDq%=-p(VF2.>W9Cx,Nf`NUf0upuoPWWphNpx?C'm,fSSW7unTpP@1$C79`aXoA,*px`0s0#P'@h2 # 3@i*(0" p`=Vd" -T!ixf XjG 10m?дI'SP:LF'3OWWs(f(yyztH{8npfeG-VdHuU(oSnXŏ J+)R7u`D @o?d|MfP:sJqX5" p3 il:"sX $* :Ph&Y_$1 0bZXp>ӉQP+U1$5 0PMSH@45, @-ŋm?nP6=tqy qeҕTarHzT]3-J(8Mu]DU@D5f8:;IJCmP@IHu^=Zv@h`ġFf|p0Um*8j Y8pd#XPLxb b]@wk)**2(ٖ큄0SSHHP6H?S?TC]3#>bDI*sbl'6S{t{#ҭzq~0T(6HXoXb ttRuPSp{6 A"EI|X9`i5  Ѐg *؇P,ʙjvP'En6P\8$ \2 Ɣ((_4 6@084 u2X5-8a0DRhC걎 @A4Hy@u5=2MOXOKp%kf|.tt!Ve8Su(Uq J]~elPeHh섂 m8pLRh^#H xƚ mU6H:8P wS"2(Kɔ`}QS1 b!Y ` 4%Hv5|MJ9S&z@EzK^/#UdΔ4SsfLJ{yaRfsxU@U7輴{>RTp+jHI:a*ipޑj:#^ʓ`<+:H kWɇ3@Hm\\؀'oy3h9 4p2i~7QUYFPRRP(80l$TI?Kw-SVo(*aBUjgh2ka{}؇{@rҵϝ}j>bk^g6Ok뢗kUĦzWJISr&O7jx@PM\ BĖ-@HPi 2\Lp-[(Q!3C[iC@je4P „ Ԫeͻ..l8^" 0 I(5#(yUQU^YUHReTI߼0'UKt{M7K̕gܲy摫>޽yꥫ[=yIGm\:yuW\tJu?n e{,KY=-h99Oyc!=)n@x uyzF$I8Hy0d  (H41 DBs!ۘ63E(̀iC 0 hNB XHڈLXeS0# l6p+X-sD$K.g蓟 tE@ф! &@U08 (>)UJx8 aߘ8 GCxQ7T9u3ǹkuS8ۈUX'A Sxk@" Ic(02 l` R8@pM@h@2gh\! @ (- (`(&A4P0*FЃMSй.A),J$D<$8+Ç!@Bٹ%0p­C<7P݁Å: >A-uB'` 8{Ĕ:M}η7:@93#5؃$AP@.Z (ʠ(P !hC̀ E#L P t@d*4B&ȁ,pY&CA TS| <1jMqa @d@ @p)!5JJJZJ'@! CQ;%:A*!܃>܃Onґ|-2tGB3rxRG=胯<$)36p\pR ( ՔAq $4 TA ٔ yR̐ ADRBBdA;B(.5.Ģ,%1l($AAb A.AOZ`ޓ LR$@$@}sY@܀|)/\v]]% 0G B*8Ԛ :Cq7a?Ƈ>! {Ҷ8K-Kփ]5>'4:d NPI>z==C$B3O3Rkpd)|C "'A̴/M̀2 L@eI^PsP@D0T.X.\5.dn/\;_ق5Ǣ-5d\/`;C  `JؔDo*H (AΦ5C|D)z]KY«0Z=!pEABK$ȧ$5xB*8C$%?T9t+l#F$8;t2~9X/I䜂7H4` ^D LPca(e`HEh֐PCd-%-l1 C/ȁ. @Hh;,g.l&lXkie'QŹD׉+b)3!x4z4 4szoxÊ!r`T}80 <^BL @<\M,90"KO_3Tyq#`8LB83T& )@CBK |5 [ԸU M F81H^@k%C.|@k.e/ &lCg4,.%l\h\h(́Ҟ.EZ,, A'L tjdI=# *HdKi,AhB#MA6lA*筊BlNHbRz=,348H@@耭7ϰ8G{Xы7wq) c_dn4E&jzF̀(E> X9/B`Ai.r,fB/B8 dA;A\%T@%; ş^H4R R@R A,] ,i8\&(H? 0$ QJu8/HSB@l+W.U'*ze8KPqS^:fٓ7tkfNH *R1[tum\7Oơ*a$8n\ @dL 20$~0Wg(Pl2"AZNHgS}z! pa76qC^ JvT[! 6p@F'j`LJ(*`-4  %` I(c J,H谲$֥90+ʡd C 6!K*x58]. y8rh`tX7QfXALgOD1[9Є#vK/06 AXDA[JfPl-#[ Ѐ @h@{!T.LdYdJ[8tѨTX& Ld@0 UP$`j+~'@;x\5fG N$H@`ѥ7|B d]*0,oJ*UL$tm D:1p `E$E'8g@O<$‰pI`KWz O<ӭ*԰=`C%P@ 0JUR'{UL ]< UxPΈQ0+LAZ%M @Ѕ-JkF@`xs NAF *>Nrnc4z@"<:fmE$nHr@dPa(NXF9A$8 MسmL $!|&t@үրa&LV`\a"~"!`! *jR(a**.<^ pPA)`@ *@fh&Jfbs M-@ pA2a.!x D2v`Q<%m5tF ؀k: TB!\sPL8V`^  z8<"* !ViN j&B R @8|A@-@p@?RNA80!J2ơ!T⴬1u"ơgL!&a#M{T2` T!%`(@ f\H"ohʠh"M /l,jjfr fO@&#5¡ }( B҈ `FA+B8LV,1< z@<@ԂVz ^!v" r j&p@a ,`F(0en<.a(%rz a(p`, ơaE& ""0 $Aq@1^Ā((p^`af"  `@KvhhԢ-@".f& /v֭ @zot x@:EQ%@B! R FpR%_` J +)g*-$ b:*@j ղNF :` ( V!:fA^M9|a @ȏ,'r&@_j 춁iԡP!nP!SP&!aRA@ Ġ @Fv @ TKꠖcJ 0d*Kg\ `a012t! 0A Lv !xa `PA  F%46  :`  ט0EUVJY^@` R@!ĩ[u2(R:,R!)R^cj3`40ؐ  r j`=pL,ˀbDSA6A,@@ASAa # DfaTuD@ ք="sn8&Fl@f\9# 2 lV a<. B!pAF@`܀`BvheX$n a !$0 @ ~ DJ@G0l *d$f+`@f2V8Qv,Tta, ܡH`gd^xj9v'j I!&,@ Ԡ~m h |A8 5d nJēps @lΓ+̫P`ΠTFeD ZMJsqr .!ntA|!~z1XP(SP*yH0'/d]Va,Lc `@|D" vA,Wj@  0,;tVDVVրaa(2|$bL`Yn~ vA La H|X*`aV*p,  =jLso, Nbf1cp p2V2lov 5aNRڠ B~ 0 APt-0𕄮P ` ` wz< i"@ W0 Nop`z-!<` ayD|`a@ #@j״FNbp`<|XwL!@a`JuީHa J:mI@r!\Р,$*xS@i /a@ !@32 DPD6@  8D@x)H l;ٓ4F4)J@!(|2 1C&)YE#>)PAt;LX,q٘:dI?5քlDjߊC ntsRn K5e_\y*Ȱ"it }U#7#@o<(p9#0.3 F.L .dȀB TX#8"KP Ti 1JXG(|“(Ys=Xd" VU&#RHQ8 ! hEu s@h '%JA-@dDaM`A>8q*hG#%}Hl`pnP |5ܰ$5, *tRAjLsdmJ) ~$ޠ"'$Dff0 i{'o@0dDh eLKP (@u䑈$.L[- VKb4.Ąg4 )ЁE;ȡ/YX-bK8@K Ip f$Xkȑyv1@ A, D09E, eA9dv"& HiƩ09Xn|J`b/64$ؤ SDj1%4NTDD,00@C3A4N/mp@ xгq Cܒ (q%0 ;-1F)P4ArtBv!I85D! Q`C2xB^`$PC\#P;BIZ ~ L`B\AJmg LȁmE BR")Aèk7(G* L$0 @ 1L_İ't">  ' 3`U PA a/ 8ـFd@~2\/@!Dh8 >>A A`@&*":B0.3Wt!.@ g7BgPQBlp*ȡ`2AjT,`@ˏH-iZ&0 ~CE4d NrP[G-.,\ӊatU<2PU9>0@%T7@'*5 p$PG"`#}Q:D0"#P6/J`4 ^iA, F HWPrCE > Zh<pI84 6F4`0|,Y4~PjSU@f3uB`3p`2&P]M ]Z@e'JQ~-',QbEHMiFSCNkj75vÆ4AX3 5(/@P_f0"duGp  `D|!^T؃C^ 7C{C/W$&*k yHxpQ LИFj`Ұ `u FPf98 `48$F ݅k[c ;\AG = טj/&EFK!*_Xt24L6԰@Ǘ%xS TI'2Щ"BP< x ٘=!=T = !>5?!3HsdPDU,K岘-yn@p1* p9 /AǨ*T@d_1"( ఌPm CZzUzb |MXz6CZԌh!R?0Bէni SV,UY a+ ! ,`Kh a/~5 D(NxC6زzqD8>0ЃZ(-i G@þ3M7B><,iI[,X A(C4B7=y5hW $ !7A)p>Ld  @zM+?-]0 t\1D=[07p ]4 `7ej2U] 7$u1zs 5Pp!0-=xIhj0a6DGFPQ5 M@oPIc /P{ +v  Y{.nr!n>+ 7eʷ|ҧI/ WbAfP'+'(ZgU`NnCBWc&5!M.3 = d ȀH_Ѐ-` FX'b'và0)jP /jfRc'+đ` aR qd`$D/@ /PP f@aMpD/J z.( 8eO\ʗ؈02L 00g  0 рg npg` |s0S2(PGd!( he xYS[v`^^0-`0i -`w'DX B80 v+5v 1Fkj]gv p}P` E`$@$G%|aU=pX7h/pXce /z.Y(34i|<ٓeKG$rh#/n3h2 )s6s(0"drQ0a ct.Qc)ڀv+X_`HPX ° }8\daǙ$^)5v ܸRXQr* yB0 V*b/%@ `0%`5w7P&P0Pc  42!2h@0nN&N>̴"bQ  7e0|"BuȨL@ @{P\2hÇ_VI8i&dx\ 5C.ZvaĘ]OW/!@09`D8'bWEf @dw tpbro,p0*$`SEB*.I B uk)1ih5 @'T3 UH0*EKje|͔|xs"eB#*Re"Ee S 01sJoEd%{ 0ň@pB][s9w h0:]#@;uueu %8vkwPRP P8j O! Et: NTy.S`,`C)~Qd)of& >8 4e 0n R拾0۳K1SfLj3(P1gfb 1R5$sPCc"9TC ɗv yc@14J7Z` < } vv: ^ 9DPpM7C bk67 ӃUl> ЦʒW4$&'Ds@P2ٰµ(3 haȋ|Rv";?X&3d2W V[$!Hc8Q!h7 +DmB]z_ wx)1pG Y[ S6  v x^wvIDPN0 pHDq8rb n@0,8'-k+K:XORQp9CPQʻn`9&/ Wl]OwP a0Φp`0laj mm Z 0n͈p\pW Ā &^ \ ˎΜ oP*{:^H@KI E ɦ#%i/HTm⬴}p%0 ހg2im2}pL""y w1ep'RCEP*"mJ{,`` P0zp AbawNa t Xp rA[p S' S? B݌ P $.T{C 7 jp"ҽS#fP?!9}W~y r1璥:41x0v$YeL0FKu% {Q nDt6:l pH<;@ İX@3 &x CDm))  Dnir@͛5J080 onyȁ 8 , 8(@DY4oN z\(@ m-%kYiծe[c.H!.&4 LP:vB[2SR1A%J1D$t_0b:Tۑa(E.]z~Bԕ @W)n!"F!C("D8 ]X mF MlQ"p0@5HBP\B,i.8@@# Ȧ<0 j,ƌȚ+ΊFsT+Ʒ`(dh1 @8. C&31"`(Q $an(B jA%HĀn:d: C~C"#Dv@[⻄!Dvq1dDv FTNIRD2c" 0:) $(" z=@%|J0dppazg yD `h^ |,Ԫ-뵗zRĨAIPHK`>c. JbƬ=x0\`&(Ig} #6HifOfM;÷r4B^. Cd ANXiE)bNb C ADҥ n,* J]9""<WA\RZ2Yxct $0CzQ}艌r:Í~Gnw5=1(c^"0;p1`jEh\)$P [a0Zb'8&z4D PN(qfWœ༘A=%/+ziB)_hyΘ"WD0&6  e PA l (ޖ8K+ j-@5>7c5r!F p-dZH$@(ʚg4i(JPK C4T,I`HS*. _$TI.p %4a ; &\9SF'f|$_|1{\A/A 0x02 `;ԙ/NAtq -=ATnKxOTp" @xAJTB@7,wPLWT2J06vfP3Ar..j/ b O#"t)H A:q\+M:1BYZvћ> X&pix /֚ bҐ9DhCff8,TR9.c 1&4kn$! S0C 3T':u LFu״5ߢPD(J#bNpG hH@xk Ug~0X"|!@"D4{%R7Njxu"PX0쑶6iXzCA)@<dlRC4ASb hbi\ l CH}[݄ HE7n@E)J4( vt2怇QDoAWBx%-9!p"@v&5* p6g?YyGl ('6} eE$p%]nrm?ެQ悀#4 \tew2@ī u&@ʘ2Aۤe`8xaׄA 2Qoxp28 Jd2 ;(o aZ$ ΫiB_P52+]Mp M %Ȁ%`"!r;k;  p2hBP@3@}ؐkn"2p<( p7[sHs_ _Zݪ38(^p !N٘`.h/0ΦJ*tXtЬix ;$J<~pltD`0`MZ0M>V#[@M-@+\8#ЅMc;@Nh}63`7$pP[ftFp*P>m0ꢎX ̛ۖ('¹z [f`= eI&`JX\VPa؟Y$aGl$kzh@}+bMJ$84NDCTpO؁)pcD+ ˅QQ@;J"H&EН<n|ȃH!{$0~07UdEBY>ux>gxZfjq&RV_op\!!X)S0ppE8VVf g=b,Vg}xb6=yp5`(Z@cH?vX(]ЄK.@ +. %n ,W܇03<`[ r$`*>`ŦtƻP\pXXF8Іg.|fIVF^~tH? kCy) 'x^>ȁCXEhE`V H1I.6NT#Vg&ևڵ+D?<(=*CebDDPO)+؄[Z\+6,R=p Ѐ hvgkwyoH3X$Ї2px_$p&\=UFH kwe2xOu8jm8hQ8S6?J,W-%"X@0>8VFhFX$#;hu}xN|y߃H$<$ i.`8 @4Z BOQ]5Mb% ?lpG-;l .bpa?bL 2E#O|uM0]8ި*)BBcj 1ZS2v X ҥÕ+Zㄇ]YNlsB=xH?F.0$ȑ%?9 9x"%/ =nPQ UO,qE0\n6U /0B $qDܰ:" ҈b5Ofgט >=s 4\3њ .1MFS[qspRL1Bb@hqEm7 T`A`q*ET(:Fp?000B60@Y#1f3 N'=AuRG.HՎ6PUa B 84f #j% @D[c D"cMh=+=x,t` )KV8`y@hs1 #ŤHB*>O:v Yv?z0Q9#Nt*7A P*ABtV0B}H2bvzЈ#d5Ġ5(!J0z`Q(;A'vO$6 =p m6~TFj]P0F8q."`c7H8\#@&8BYĽZZUӮ$ULUx9ĭو̐^[F"*R th%8C'*˰x2F~8MIA t|B jxCE]G!y:,f#C$%Ɯ#< 7 |As)R̜t R^TBk0ֆ$o81#^`)S*pB9T:آG8a wC`&D|fK}D< Bp-؀}8 N "S"j!B|0ؑES&6`z8r{І!e12|G4O9,@(YlS8,qTм9.a KgZ 0.]Ԧ^%8@lPL2Zky*~51lQ؇jRkZsBX_l`Пz ;{!J0wZV $=q.C|] nE>@L,Sj@ƿV5zJ?ZgP\mV[[`2Pa浯ttR RH \/,u F!=zcbr@EOC@Jysy(  Z9^) :lP`C5 `LTӔE y\a ǡ/ B8X;-@LNxDD=`T@ha&؀X@`@1X`_Ay>)H)E%A0 @21Co--܂MRGpwBhGe\%\A` F+Z h]>4HCzA4@ t@YjWh&\Lz3Ʊ4 ZɞC@xб`夊H EЄq ~h` ӯa-$$'=܃ii\-&|'A`BtGop-@@|Z^z0Kn dB8hAYxJY 5b,NC5`@ \(LC8dd^XD4~HlA/䟿  Z@ D <4d }\ {J1)MUuYMHa&x@hᫌ@'ifڍC@*i$:/)(ֽA@$FD&R0"2<1$-`0|dψ4G&~xKڛӸ؀(-; ;䦜ӈ e, 94H4T0nL4$@ <` &$'lP>`7N~YUU UAYI5`_ arTT mDb.fhm` $ T %h@)$>9==p$6Õm.'\A`D-;C1,0b0$XTHfG`vxHکqvjgY q;'yDYzQB"|>4@C~ tRp@@!sܝ0KYaO7Vc T(^0& Y.XAэ0hMFc,1a.]yzh%$$ kB̓=C=p Ͻ4TCɅB-o*1F $s~@vhAB1#&@vg @lr;C>_dj{F+a.xהq Ay plF-pB$j1WNq@ bށ B.T@ =NT@#55n-10!E4\&GPD9kkrIb5%A.A';,4E&&&@'&i5i@&1_hN.~'@;Ѓb}%r@:qHF]"hJKF m \yT&&%lN8A(lD xD T%X OX@`+'X:JR :TCC L-"EEĮ$&~J\Bj>|y$/z%o$>..0%l4לH @\Dq$s$^oo"۔xhmTQ-B+N@ $.Va65\A lA8(LD@n(x:4M mp& d*@pnL<;1xqD~q[o/:/ޕ$l;63@ ~;$rܑC5\J>ls Tj ME ,8"" 3qޱ &rӰ`A&r%x\O(0Wc.W U)VU@yuY(4m.\zj8H-W$@ב A^A2/ü8|7==@(>h.x.lu7o!1fD 1jHNB":-r_zNq1& K xZ/ծ@\C8jB;`G k]ZڱL#yOAsJ6 ~@ B84`F.PmLBEBdρ`yrĦTA\K.l/Wtשkj$/P7C:|Íli4=,=dA&P`%X_]XN!ڳ7 !AMb834;穌 1I84G/o{֛T:j5_5<"!,Пl4"hs^"r}1&rGn'ҩun"@<?@ ds'@LB|J G4\nB/17F!/Fxa`&H©66*$1;TC?5©^3,!6s30X! 0bbcw#G8@8@7 .U NllA>`$ B!!škMv+/w dqx!33 0A'ЯEiKfw7`,x/p'BLTez`2((@$%P(|Cgу4|\5ߢ"`"vFɢ,<2f`Բs:-x86o{ \Է{'oO5.!#{gCB'"0L1"(H33vHq8䣼2i$,0_y7*mJY"np9%jG\A8d B8|'/',ޱyTl`$`$@%=&24:=X%%d_=[srhɾ1R#M<xaB OqB*} ɑC I6 q2+Yzpdܑ a& SBݭDd v XR`|%*('!Ea&YvUy AK Pփ sfcnW?h2E W!Ȗ𰃇+hd; 28ဆ@҃5>D$Q..RН#JZI S2._wĀ"$ \xya+Q>"ļLKv#'s[n!&[ Ƙ`jAcIN8AE%! *+Vz`rڊ V  0@ ؂5C.хJ]1-x҃KhD1Dy|t |LAI͇IzAO¡&ji -+c vY{.<Գa,xȁ"VFZ9xocѫR,A0B zbg[j k bniJB^M_$)U_Ub4 FdwtG! a_#]BC8,Zl+ф^."C$b I%dq0pʷ ;c++-annotations-12.5.0/celeb/celeb30.jpg0000664000175000017500000003625414624364531016503 0ustar frankfrankJFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222?"C!1AQ"aq2#BRb$r%3S4D,!1A"Qqa2 ? 0` 0` 0` 0`Q2(ܨ1ObD{e H]C}?F@6lyl8pGR.m:팲aq)!q@*kY Ъ:ydE%E8ՉO ԥX/`4 ĊZH NC$Tz ?\1%} coùF@Ѹc$o$4RM8 зmIYD5Z)Ů5((닱7rq*4b|袬%'q̋?Ŷ݅<fTbl5wp Mc:%t>][^~Q DenY!"H 1OJ1UL4ϓxQQ<7,NKyQDt-*EBN , ̺Av,[彁:N|3WgefCG17RyEU.f2XX >YT\0`[$F[>sb˳UX6F-, ^c ,٧|UI=Ts$F Ɯw e%MvzK`4UH;ك=̼1, `$5% V%2SU#]_E6]_=@Q4.Q°`sb6*I 0` 0` 0` 0` ~ OͨE Lj,)*n7B5:okk7m8A;2M\n2Ť+h _DQeyÒv=`yA pi^K&n67 s*V_ҁk`]6ěH^q ԥ@^ہ5TJfU7BF`{o{aѹW+(·W+-~6:P J-"r+F1}q"jZWIl"\Zf yD YEyabeJT!Xى>1}ҤoO1{&zcl!՟]ֹ~XIjqi%l4D21n#\6H P86+ߪ6nIXV!m`Ǣ>qHٔa3i-Ҩ۷F^BZZ5m:e;t:npkkS1J4HQHF9||HWJ(svlCa}O/KnOb̔T-Qo="(#)J4D̳:".a^*yH+zoE獏!P~!!@rn]T$_v>ek2 j e:rx)[)yw:ȰI/ͥWmiGPgfQA.YUNUsjwO2d/ ͑ X TcG2/qfKE*j$MOP Ɓ"qkTP# kk+O( ԁPI˕G+E֍ L3&uf>:9-(\YI3+4 9^ zlʽS;"Q6"(s4R) cidv $RCd\e6OJYF 3Hڅ# ے9v{1GrSi]Z?3{l s(z"vGVT8[:d旡> 1Ra 0` 0` 0c8]\8"4QԽ@j@d},Ym}M-D4)caHTc2eaWQ셓<F 5By+|텕t}TT‡#Ŋ~Nhc#zcUEpeF^ N97/4+?o)-0%+)<>ߕn,>Y= o\kXQ%5$x>ZIi(GQgR= ;cG`ge ,vú'"^0ͥiLuڑ[ j) jO"܀{,cU3e>\m*ӦZWRCo}Zc `܍lHf|>t.2ܙSq[I@o~h .My6E[6Y$P(I6At88fs0LNۆkO[|7|yVSEQ/OL‰Vffk}1*HX c`pX5km^Q3p ܃q`ۮ#,Jm|k*o5b7kDd#D è:.7 (~K$M$6H!"kf&/ZUx lY(;56=lƋ1ԵDRԻz0|+{NJ3Bۨ{s۶-FzR3I'@c wTt MGY,EP΋c5r?0;ϖG`YJI8GfW$hQH ~l97fO[@I5E#*)PsEǬNLy._EXWR56c$RzlNɩK^%hy V$-a]TJOH~=KX "[t fcRs:!]TeiT]E]|!JJn"bAoPgOPɘI>uFy#ArhAH٬[IY:p~bK>s/ DhA6YEEU| '&eO dZb;^B瞕N{ a_ytpF)jYd3Fy֏PCk4t`6pQkћeO G/;ks'ke{eI=E`ɤSX'rAb_GYNk򨫩b!0!A;w{нlqEIe˾*oWj4\s֌_ӕ+Qee$\ d){Q$\L!Ajb8X߬&y½E4Ughgq Tof < <éOfM,D0` 0` 0`ii$y{Ј]‹\q4e9$p7m y_[=ŠLƞOpeodeGa*Hŏ(Qr굫zQ[øقH+:Ŀ,"b7;%QRSʜXfctMԸ.z2G% cS#ѓFNcq{vv n:7e?ćwN[]2mcͤ~?%D1Q#]u^éV^VIGi#;~؋K2fJXq}rc~WhN 3O&˞\jf5Lh`AlH.h 4JLXYu ^t+:H"] uwcmaU>{<)Т_'cF2G%r&y [ۆ#r?ǟ%۩8O,QK *#y],$秔]}BRQWd_p}:>%B" *Mtjyu_s2mmJ_6#U ؂{8S[OFz[YA'].RTG z.)UUZ@b~%n.7#¦ibő{(Tq4&Xb˓f؛okvJ#9m5nZUJ#rDߩы{ ŠJZ`G-Sr0A$qDěg`ll\/f.誘ȕՁ澲} bepoPSq)xݫLԵm54Ix6Ӧ)0+)&+f]ONW#UEusEL,L{Ā{l@ ]qRCHViYS: @$9*ZLOZB-TV="**u+XzRe5^jᕼ (rlNk E;%TP]IdBHk u'RkZYj/}Bqfҷdj\KU]H2Q$uGJ] ?LA˪i$ 2nJ'>f[#Xb*HCmSnפFd2kk 1㎪24BPoAUsUMS,D۱W8YKb6bm [/mY&"yVa'eEpBl/ɷ$gȸR#OQ܉$ +(i#hyjmka5Վ,AvS0ӴnoU)ɒz*4Hࡑ(!l{a]"Sf2VNӝIkXr\ʚ-$N%REbD52 kYur~U$-XBMIaXc{ۘZ64@UB*GKc~m"N٧6*j(a RCl&˼,E-L5sBK)_`OQ{fl2<Tié$_ނ!**"E&#O`YSZ7G8'XeiLRiSV[bnD#5PwG꧎ ]y *kUL-55uVsk~}1,~Ct}$hOAPjeRĎ@glty2hj)duHarAsշGi42 @]]a8댬2}ĵw^,g6gE_u灺4D,{lJYzƭ ۩#cl$X84N' ֘nor.9TcD,齱Qsl=Hecm:ǵERC$tz!W,AXP{n븸X~:Ji'&},I Y:Qs5Egq_#Y>wĭ494ct~ȟp:TSIu,dWIϿXaS_TӜfUY/XC&g+|4.dVEe[boŨf9O1G~Q=ʂuݵUʪXc vѩTzq`,4I58h)+pKCmu`L`&$r!ԭF:qDR,-a~Ǥ->^chcI TK6u{Q r\%ʚl]僵)㐛jMS~]/U*dd|zv.w?up沠f`OJ @?8:أ9fz2"Lrh~,;a>ql>!9gSf7P'dA9GgKӱy)?$""w`Vd(@ot8j;fYp9|" jW1#X lXsi2͠W,JFDkyPB$LmAb1t̩}审&I#}J;"[UQ/"n\^AUvJE6j;I uU_,VƋQheAŇ.0*7UX8.>̿0$bY%+VYYC],zE:qgcn">mbqrh1׸eNܶO 0ei)U!*6'O<Ց+ ð;r}%`|DԲX2>cMMGĘkjTBJ.{,{F6,`Ǹ06+~׏A ` q8d.Ys*jXȴ4k{ FjGDžIX_@e!6IqB/A'J}O-B8s*VtId2 n M{焹@i} 5S p 6cum~xx^X#F+j Z1NxOfG- lo2]ahӿSR)_[m.Go !OQIJ&CS+kYHƹ|KJNU*Cw5cpzE5RY6bʣ6{X(K(مj_Z)iauI”^,n9Yksɩi7-b452ܝv6?}&fTt%u8.>V^{x0zhT-<ϧ[ao@/Hᨠjy̡w6'9R3HhE8`9G<8%osy~L/}55)ffV1.WŚDhV.o5I[U6Z#k(?cFA3 d \mRAqޖyK^M;˝FL~K¯(P..R}t7NM @[*_0I~79TKD5p[i( qce b;1&ަ~)]曂zE!B1QF\U&BVNzfB?qhw m IqDDTyK Hjrc} }_xrWKő"xcy4~?Dh~=^¬.3 p<3Jչ炩rGGV>i2 pNL>8fU1,"b <|5fE/2j0yju`w;" k~F8-mGǖVlF6ǶǸ0lep- lt66?3}>ARfJfvvyJ<`}i1"%,7>fQq8"Lah#$D+e[L,ø$_|'3UM\`uOq؋t$L kq/G[W{ 7>{lY-,Y,,4" !ߣ6jV(eBiV'b44U2|8ʬ.GKFTt4lyV]i/&۝cB0o: #y"A<ՙ$vpn/C)#ea9T_k{p)6͗Yv~ƟęW$qģosQ($ps̐F2<MŅsuB+GB B$B2Fk4^裐?TSe&ȝtJ o1 `q;))|9%=,2Ia0_醂l8䪧HX?LP˘)Zy%`*T X7gsj(C;"GUۖXBo*zi!ddevaPuRNZJL)I:u-_^&W 9/y.q1hJÎ% Mē~g4k8gm<Uhd'[767je<2T,5D]a`mRO!b1i}@42muMrwc4k Tҙh!X]A6nD펼O+$gRP 貙uuf @ImZyv=Ui^d- LdYf`MmkbśIQL|5!ۄ`+9k"VEcI;խ\q^u0? Rw-a;vlBm)R /0plAiV'k!+G (v^}@8&F"X(Wd\Mk##c!-ϢdY=X,C~)bȩk,f.HpH EiϳV+]9?㕫%Љҷ$_5ʎ8ݝ4jӂ٧k"84ణX YbE*Z-8.sŴ|hF䍸W8p@}̲S!$6b۽)kje!6DѝǣMa)eڎŧY+!xXzu#lyN M'y_CC P#eA^:g+k*&S+Vi k2,|y}qi*(4ݒ q*8SoZ|ʚ&;o12Iҡ;=cokR/DdV tA0%/d%o\5ZK/Q\-xcC:RP4翚L `jS Q4?oũ>oK- v{9q v{bEY0Pذq~xԎI@lUOk撲*(*dkA~PX d񣢱 ̽ A!F`Ubk'$gO0yDNO ƬM 4H&2D[jnU@hʛbdRRWᛪs5KU*SfƻN ߠ`1Fx4bU,tmti)#Sb~(ҌQň ѸR>&CK֬T52R[$t{sn]dK2Y5#)G4/sDn>Ž-J0ko@Ạ6R4 XE,a7فocmA#<9,fP\H [p5n?1,4|mMڶVAI>f"{u@a 3,edz?q#Gx`Ȳ%̚.9o+/I[vmPiF 'H}`>M5c++-annotations-12.5.0/changelog0000644000175000017500000006776014624644524015373 0ustar frankfrankC++-annotations (12.5.0) * Added a subsection about constructors of polymorphic classes. * Added a section about using std::streambuf in an std::iostream class. * Various cosmetics and typo corrections. -- Frank B. Brokken Sun, 26 May 2024 16:37:53 +0200 C++-annotations (12.4.0) * Added the multi-index index operator, available since c++-23. * Covered std::byte and an alternative implementation. * Updated the description of how to implement class constructors that may throw exceptions. * Typo corrections. -- Frank B. Brokken Tue, 15 Aug 2023 09:39:01 -0700 C++-annotations (12.3.1) * Due to a small oversight, Debian needed a new source archive, hence the minor subversion upgrade. -- Frank B. Brokken Fri, 28 Apr 2023 19:18:19 +0200 C++-annotations (12.3.0) * removed section 'Returning types nested under class templates' (advancedtemplates/returnnested), sf since C++20 * updated the Generic Algorithm chapter: merged the descriptions of very similar algorithms (like 'copy' and 'copy_if'), added the descriptions of several new algorithms, added a section about execution policies and updated the descriptions of generic algorithms supporting execution policies. Added a new section about handling raw memory. * the memory chapter's section about 'placement new' contains a forward link to the STL section about initializing raw memory. * repaired typos * during the 2022-2023 Academic Year many typo reports and suggestions for updating sections were submitted by the C++ course participants Jeroen Lammersma (jeroen at lammersma dot dev) and Channa Dias Perera (cdiasperera at gmail dot com): thanks, gentlemen, for your valuable contributions! -- Frank B. Brokken Fri, 28 Apr 2023 11:42:22 +0200 C++-annotations (12.2.0) * Added new section covering 'std::string_view'. * Added new section covering 'std::osyncstream'. * Added sections covering 'bound friends'. * 'std::iterator' is deprecated: the section about constructing iterators was rewritten. * 'operator[]() const' should return 'Type const &': its section was adapted accordingly. * 'using' declarations are now preferred over 'typedef' definitions: 'typedef' definitions were replaced by 'using' declarations. * Repaired series of typos. -- Frank B. Brokken Sat, 05 Mar 2022 10:42:56 +0100 C++-annotations (12.1.0) * Added __file_clock::to_sys. * Repaired the descriptions of pop*() members of various abstract containers. * Reorganized the description of the facilities of the filesystem::path class. * Repaired series of typos. -- Frank B. Brokken Sun, 20 Feb 2022 12:20:13 +0100 C++-annotations (12.0.0) * Added a new chapter about coroutines. * throw(typelist) specifications were removed from the language, and the section covering throw(typelist) was removed from the C++ Annotations. * Added a new section to the multi-threading chapter about jthreads * Repaired an error in the US-letter formatted pdf document -- Frank B. Brokken Sat, 25 Dec 2021 15:04:32 +0100 C++-annotations (11.6.0) * Added stl/optional.yo covering std::optional * Added generic/iota.yo covering std::iota * The multi-threading chapter covers threads running member functions -- Frank B. Brokken Thu, 24 Jun 2021 10:11:25 +0200 C++-annotations (11.5.0) * Added stl/tie.yo about std::tie * Repaired several typos and added missing code examples. -- Frank B. Brokken Fri, 20 Nov 2020 21:07:49 +0100 C++-annotations (11.4.1) * Updated the descriptions of some functions in the filesystem namespace. * Fixed some typos * Following a fix suggested by Tony Mancill the US variants of the ps/pdf formats of the C++-annotations are now using the 'letter' paper format -- Frank B. Brokken Sun, 30 Aug 2020 13:36:27 +0200 C++-annotations (11.4.0) * Attributes covered in the 'Intro' chapter were moved to the 'Attributes' section in the 'First Impression' chapter. * The section about Concepts (23.13) received a complete overhaul. * Added FORCE_SOURCE_DATE=1 and SOURCE_DATE_EPOCH=0 to latex runs resulting in identical .dvi and .ps documents as long as the content of the source documents remains unchanged. -- Frank B. Brokken Wed, 04 Mar 2020 11:47:30 +0100 C++-annotations (11.3.0) * Added sections covering the three-way comparison operator (<=>) and various predefined comparison classes. * A link to the Annotations's index is provided in the pdf-version of the Annotations (it was already provided in the html version) * replaced string() constructions by string{} constructions -- Frank B. Brokken Mon, 16 Dec 2019 11:31:20 +0100 C++-annotations (11.2.1) * Just one day after 11.2.0 Jurjen Bokma noted an annoying flaw in the description of the move constructor (section ref(MOVECONS)). Enough reason to fix that in this release. * In addition the description of the copy constructor's characteristics now mentions that the CC should shed excess capacity. -- Frank B. Brokken Tue, 19 Nov 2019 21:09:07 +0100 C++-annotations (11.2.0) * The std::filesystem namespace coverage received an overhaul and is moved to the Namespaces chapter * The std::chrono namespace coverage received an overhaul and is moved to the Namespaces chapter * The sections covering error_code, error_category and error_condition were rewritten. They are now covered in the chapters Namespaces, Exceptions, and Advanced Templates chapter. * Added the (internal use) program src/verb compacting verb-macros. * Fixed typos and inconsistencies. -- Frank B. Brokken Mon, 18 Nov 2019 13:29:31 +0100 C++-annotations (11.1.1) * Clarified the use of lower_bound and upper_bound. * The introductory section of Nested Classes was updated * Typo corrections -- Frank B. Brokken Fri, 17 May 2019 14:39:09 +0200 C++-annotations (11.1.0) * Rewrote major parts of the sections covering concepts -- Frank B. Brokken Sat, 09 Feb 2019 10:46:52 +0100 C++-annotations (11.0.0) * New major version covers concepts, modules, and transactional memory * Several sections were rewritten: unrestricted unions, lambda expressions, the std::filesystem namespace, structured binding declarations -- Frank B. Brokken Sun, 02 Dec 2018 16:33:07 +0100 C++-annotations (10.9.3) * Migrated from Github to Gitlab * WIP adding elements of the upcoming c++2a standard. -- Frank B. Brokken Mon, 25 Jun 2018 12:48:37 +0200 C++-annotations (10.9.2) * Modified src/trim so that it can be used as stand-alone program. * Version and year information are now in the file VERSION: build programs updates the file yo/version.yo accordingly. -- Frank B. Brokken Thu, 18 Jan 2018 13:16:24 +0100 C++-annotations (10.9.1) * Various typos were corrected * Removed the nbsp() macro from preamble.yo -- Frank B. Brokken Thu, 18 Jan 2018 08:34:39 +0100 C++-annotations (10.9.0) * Added extensive coverage of system_error (chapters Exception, and Advanced Templates). * Covered the namespace std::(experimental::)filesystem * Added the constructor expecting an initializer-list to the std::string chapter (chapter 5). * Explicit references to the C++17 standard were removed. -- Frank B. Brokken Mon, 04 Dec 2017 17:22:06 +0100 C++-annotations (10.8.1) * Fixed additional typos uncovered by Amazon. -- Frank B. Brokken Thu, 08 Jun 2017 12:32:50 +0200 C++-annotations (10.8.0) * Added a new section (Introduction: upcoming C++17 features) providing an overview of new language features introduced by the C++17 standard * Many typos and suboptimally formulated statements were fixed, many of them very thoroughly compiled by Maurits Silvis. * Coverage of (considered obsolete) binders and negators was discontinued. * Internally, the previously used script scripts/patchlatexidx is no longer required. -- Frank B. Brokken Thu, 08 Jun 2017 09:04:27 +0200 C++-annotations (10.7.2) * The section about implementing binary operators was fundamentally rewritten thanks to suggestions offered by Wiebe-Marten Wijnja. * The section covering the ::template syntax received an example showing how to call a static member function defined in a (base) class template from a class template that is derived from that (base) class template. -- Frank B. Brokken Sun, 12 Feb 2017 14:22:58 +0100 C++-annotations (10.7.1) * The section about implementing binary operators could somewhat be simplified. Also, some additional clarifications were added. * The SFINAE section was provided with explicit links to sections where the sfinae principle is used. -- Frank B. Brokken Sat, 04 Feb 2017 11:34:26 +0100 C++-annotations (10.7.0) * The sections about implementing binary operators received an overhaul. * The section `Adding binary operators to classes' was rewritten. * Added descriptions of operator new[](size) and operator delete[](pointer). * The section about lambda-expressions was extended with descriptions of new features offered by C++17. * The section `Pointer sizes' in the chapter about pointers to members contains an explanation as to why pointers to members are larger than ordinary pointers. * Added preview intro/cpp17.yo on the next C++17 standard. * Added a section about selection statements with initializers to the `First Impression Of C++' chapter. * Added a paragraph about increment/decrement operators being deprecated for bool type of variables to overloading/increment.yo. * Added a section about std::exchange to the Generic Algorithms chapter. * Added a section about `if constexpr' to the Function Templates chapter. * Added a section about folding expressions to the Class Templates chapter. * Added a section about class templates template argument deduction. * The section about using non-default constructors now contains thread-safe examples. * Fixed several typos, processed several suggestions received from readers. -- Frank B. Brokken Sat, 28 Jan 2017 13:05:50 +0100 C++-annotations (10.6.0) * Added new section (Lvalues, rvalues and more, first/lvalues.yo) about various kinds of l/rvalues distinguished by C++. * Added new section (Standard Exceptions: to use or not to use?, exceptions/usestandard.yo) about the distinction between standard and non-standard exceptions. * Section 'Allocating arrays' (in chapter 'Classes and Memory Allocation') now describes how to initialize memory using the 'new Type[size]()' syntax. * Section 'explicit conversion operators' (in chapter 'More Operator Overloading) received an overhaul. * Changed uses of shared_ptr objects to unique_ptr objects in stl/uniqueptr.yo. -- Frank B. Brokken Sun, 30 Oct 2016 10:25:03 +0100 C++-annotations (10.5.1) * Fixed various typos and completed several cosmetic modifications -- Frank B. Brokken Sun, 24 Jul 2016 07:41:38 +0200 C++-annotations (10.5.0) * Rewrote the section about converting time to text, covering std::localtime, std::gmtime, std::put_time as well as the full table of put_time's format specifiers. * Removed the sections at the beginning of each chapter encouraging readers to send in suggestions for improvements. Instead, this encouragement is now shown at the end of the Annotation's `abstract'. * Updated the kindle-book conversion script, so that cplusplus.css is not used with the kindle book construction. * Several typos were fixed. -- Frank B. Brokken Wed, 23 Dec 2015 13:09:08 +0100 C++-annotations (10.4.1-pre) * Improved the html layout, following suggestions by Harmen Stoppels * Removed repeated 'mailus' files from chapter openings. The 'mailus' info is now shown as part of the abstract. -- Frank B. Brokken Sat, 19 Dec 2015 22:19:18 +0100 C++-annotations (10.4.0) * Added a section about reference bindings to the Overloading chapter * Added cplusplus.css which can be used to fine-tune the layout of the Annotatiions' html conversion. * Standardized the installation procedure * Fixed typos -- Frank B. Brokken Sun, 11 Dec 2015 17:12:31 +0100 C++-annotations (10.3.0) * Added new sections about expression templates, about attributes, about shared mutexes, about shared locks, about heterogeneous lookups, about sized deallocation functions, and about moving and swapping streams * Added new C++14 elements to relevant sections * Reorganized the section about lambda expression * Added the file ./compiler.im providing all #defines for compiling the support programs. See that file for specific information. * Fixed a compilation problem encountered with g++-5. * Fixed some typos. -- Frank B. Brokken Sun, 16 Aug 2015 15:21:10 +0200 C++-annotations (10.2.0) * Rewrote the sections covering the regular expression matching classes. * The section about lambda expression also covers generic lambda expressions. * The coverage of binders now concentrates on stl::bind. * Added a section about stl::placeholders to chapter 4 (Namespaces) * Removed superfluous 'return 0;' statements from main functions. * Conversion related stamp files (e.g., html-stamp) no longer used. Build-commands are now unconditionally executed. * Added a section to class templates covering a bare bones implementation of not_fn, which will likely be added in C++17. * Added some notes about C++17. * Several cosmetic improvements were made. * Html files now use html5. -- Frank B. Brokken Thu, 28 May 2015 12:06:01 +0200 C++-annotations (10.1.0) * Typos and added a section about regular expression, moving the topic from containers to stl. * Fixed various typos and inconsistencies -- Frank B. Brokken Wed, 24 Dec 2014 19:54:28 +0100 C++-annotations (10.0.0) * Added new chapter: Multi Threading, containing all previously defined sections related to multi threading. A paragraph about std::distance was added, some typos were repaired, and other cosmetic changes were made to this version. * Redefined the standard verb(...) yodl macro by a version which does not do the extra newlines before and after the verbatim section. * The build script was extended. The support script `pathbuild' is not used, but can be used in cases where an additional element to PATH must be used. * All verbatim file inclusions are now run through the new release of yodlverbinsert. -- Frank B. Brokken Thu, 30 Oct 2014 20:17:12 +0100 C++-annotations (9.9.1) * Fixed LaTex formatting problems rendering (in particular) the cplusplusus.ps/pdf files (note: cplusplusUS) less useful (cf. scythal's user review on http://sourceforge.net/projects/cppannotations/). -- Frank B. Brokken Thu, 05 Jun 2014 14:16:31 +0200 C++-annotations (9.9.0) * STL facilities for specifying absolute and relative time were rewritten and are now in a separate section, instead of using subsections of the section about Multi Threading. Sections about condition_variables were also rewritten. * c++0x has been replaced by c++11 -- Frank B. Brokken Tue, 03 Jun 2014 13:24:54 +0200 C++-annotations (9.8.2) * Extended and completed the list of available type traits (in section `Available Type Traits', chapter `Advanced Templates') -- Frank B. Brokken Fri, 07 Mar 2014 14:49:22 +0100 C++-annotations (9.8.1) * Added explanatory paragraphs about using static_casts to derived classes using shared_ptr or unique_ptr objects holding pointers to base classes (cf. the class 'unique_ptr' and Casting shared pointers) * Added explanatory paragraphs about defining (const_)iterators and (const_)reverse_iterators (cf. 21.14.2: Implementing a `reverse_iterator'). * Added an example showing how to declare a bound friend function template to a class template (cf. Templates instantiated for specific types as friends) C++-annotations (9.8.0) * Added a section about static polymorphism to the class templates chapter * Removed the `text to anything convertor' section, which is now obsoleted by existing std::string conversion functions. * Removed the C++11 labels from section headers, as the C++11 standard has been implemented by g++ 4.8.2. Note that the --std=c++11 compiler flag is still required. * Several typos were fixed -- Frank B. Brokken Sat, 18 Jan 2014 13:55:37 +0100 C++-annotations (9.7.3) * Fixed several typos. -- Frank B. Brokken Wed, 21 Aug 2013 15:00:30 +0200 C++-annotations (9.7.2) * Repaired some minor flaws, which were still waiting to be processed. * Added for internal use steps to create a Kindle version of the Annotations (see also http://www.amazon.com, look for ('c++ annotations') -- Frank B. Brokken Thu, 30 May 2013 12:45:58 +0200 C++-annotations (9.7.1) * Added changes of 9.7.0 to the Annotations' `what's new' section * Release 9.7.0 was not published as a separate release. -- Frank B. Brokken Thu, 30 May 2013 09:43:34 +0200 C++-annotations (9.7.0) * Added several new sections about time specification (stl/time, etc.) * Added new section about 'this_thread' (stl/thisthread) * Added new section about locks (stl/locks) * Added new section (classes/ambiguity) about Ambiguity Resolution. * Added new section 'system_error' (exception/systemerror) * Added new section 'the class `error category'' (exception/errorcategory) * Added new section 'the class `error code'' (exception/errorcode) * Rewrote all sections about multi-threading) * Rewrote the section about lambda expressions * Replaced references to `ascii-z string' by `null terminated byte string' (NTBS), following the C++11 standard's terminology. * Repaired flaws in function names and return tyes of several sto* functions in string/convertors.yo * `0b' constants are not mentioned in the C++11 standard (but maybe compiler supported) * In section references `C++11, 4.7' the `, 4.7' was dropped * intro/main.yo was updated -- Frank B. Brokken Wed, 29 May 2013 20:11:20 +0200 C++-annotations (9.6.0) * Updated the list of C++ keywords * Added advancedtemplates/noexcept.yo covering the noexcept keyword * Updated the string chapter -- Frank B. Brokken Thu, 10 Jan 2013 20:23:05 +0100 C++-annotations (9.5.0) * Updated (to the current C++11 state) the reference of member functions of the Abstract Containers. * Added a new section (Allocators) just before introducing the sequential containers. * Rephrased sentenses like 'this member s' to 's', in particular in the chapter on Abstract Containers. * Repaired typos, reformulated the section about nested namespaces (Meir Shani). -- Frank B. Brokken Fri, 14 Dec 2012 12:53:53 +0100 C++-annotations (9.4.0) * Added new section make_shared in the stl chapter. -- Frank B. Brokken Thu, 28 Jun 2012 20:48:47 +0200 C++-annotations (9.3.0) * Coverage of the static_cast and reinterpret_cast was refined, following a suggestion provided by Gido Schoenmacker. -- Frank B. Brokken Tue, 06 Mar 2012 20:34:11 +0100 C++-annotations (9.2.1) * Starting this release all release tags (using names that are identical to the version number, so for this release the tag is 9.2.1) are signed to allow authentication. -- Frank B. Brokken Mon, 27 Feb 2012 13:42:38 +0100 9.2.0 * Converted scanner generations from flex to flexc++ * Rewrote the Concrete chapter's section about polymorphic semantic values * Rewrote the Containers chapter's section about unrestricted unions * Removed the Concrete chapter's section about unrestricted union semantic values -- Frank B. Brokken Sun, 26 Feb 2012 17:10:55 +0100 9.1.0 * Added sections about features of C++11 now implemented in g++-4.7 * Added a script to create a beautiful C++ bound book * Repaired typos and stuff -- Frank B. Brokken Fri, 20 Jan 2012 11:50:01 +0100 9.0.2 * Removed excessive use of the verb 'will' from the Annotations. * The required operators for each of the standard iterators (input, output, forward, bidirectional, random_access) are now explicitly mentioned in the paragraphs covering them. -- Frank B. Brokken Mon, 12 Sep 2011 16:01:07 +0200 9.0.1 * Repaired some new annoying typos and slightly rephrased some paragraphs of the `Koenig lookup' section. -- Frank B. Brokken Wed, 20 Jul 2011 12:21:33 +0200 9.0.0 * The form of move special members (move constructors, move assignment operators, other functions defining rvalue type parameters) was synchronized with the form proposed by the C++0x standard. This resulted, in the Annotations relaxing the principle of const-correctness, and in modifying the declarations and implementations of move special members in this release. This shift in position (adopted by the Annotations since its very early releases) profoundly affects much of the Annotation's contents, and warrants an upgrade to the next major release. See the remarks in the `what's new' file for more details. * Several sections were added and sometimes moved. The section about 'unrestricted unions' was completed and moved to the `Containers' chapter, and an new section about adding binary operators to classes using function templates was added to the Annotations' final chapter (concrete examples). * Repaired badly formatted LaTeX table of contents: see bin/latexonly * Many typos were repaired 8.3.1 * Many typos, textual corrections and clarifications were processed, almost all were provided by Francesco Poli. * Sections about move operations were split into subsections * The Portuguese translations are lagging too much behind. I've removed them from the source archives, although they remain available at the svn repository. -- Frank B. Brokken Mon, 20 Dec 2010 15:25:30 +0100 8.3.0 * New sections about various (member) function adaptors * Sections about statistical sampling functions added/modified * Sections referring to C++0x elements now assume g++ 4.4 is available and the required compiler version is no longer listed for those sections * Typos repaired -- Frank B. Brokken Tue, 07 Sep 2010 12:12:18 +0200 8.2.0 * Bumped up the version. Should have been done earlier, considering that the 'what's new' file already refers to version 8.2.0. * Added 'export' to the list of keywords * New typos and unclear passages were processed/improved * KNOWN ISSUE WITH THE PDF VERSION: Due to a known bug in the ps2pdf conversion the pdf versions of the Annotations may show multiple Error: Illegal entry in bfrange block in ToUnicode CMap error messages. Once the bug has been repaired a new sub-minor release of the Annotations will be made available. -- Frank B. Brokken Thu, 26 Aug 2010 09:03:37 +0200 8.1.2 * New typos and unclear passages were processed/improved -- Frank B. Brokken Thu, 06 May 2010 19:39:46 +0200 8.1.1 * Many typos and minor cosmetic flaws that had escaped the previous update were processed -- Frank B. Brokken Thu, 11 Mar 2010 21:00:43 +0100 8.1.0 * The text and examples of the Annotations have completely been overhauled. Before this final 8.1.0 release two pre-releases were issued, partially completing the overhaul (see the two entries below) Over the years many inconsistencies had crept into the text and examples, that are now removed; streamlining the text and the examples. All of the code examples have received a work-over, removing endl in favor of '\n', making virtual functions private, etc., etc. Many sections labeled C++0x were improved and sections in the table of contents showing C++0x now also mention the g++ version in which the new feature will be made available, using `?' if this is as yet unknown. No version is shown if the feature is already available in g++ 4.3 (or in one of its subreleases, like 4.3.3). I received a host of suggestions from Francesco Poli (thanks, Francesco (and several others), for all the effort you've put into sending me those corrections). -- Frank B. Brokken Mon, 01 Mar 2010 09:11:21 +0100 8.1.0~pre2 * Cleanup completed until (including) chapter 16 -- Frank B. Brokken Thu, 24 Dec 2009 11:36:44 +0100 8.1.0~pre1 * Removed the 'template concepts' section from advancedtemplates: removed from the C++0x standard. * Started a cleanup operation on the C++ Annotations aiming at improving its internal consistency in examples and text. In this version completed until (including) chapter 8. -- Frank B. Brokken Thu, 05 Nov 2009 21:08:10 +0100 8.0.1 - Added --std=c++0x to the g++ compiler options 8.0.0 - New sections added describing elements of the new C++0x standard New chapters: name spaces, generic algorithm. The Portuguese translation of the Annotations (in the contributions directory) are still at version 7.0.0., Sergio Bacchi wrote that a new version is currently under construction. 7.3.1 - Readers are referred to sourceforge for the C++ Annotations archives 7.2.2 - Textual modifications and minor modifications of the programs due to new Bobcat library. 7.0.1 - Processed extensive feedback received from Eric S. Raymond and Edward Welbourne. Reorganized yo/string/members.yo. See the yo/history.yo file for details. 7.0.0 - Added new chapter (advanced template applications) and changed many other things. See the yo/history.yo file for details. 6.5.0 - Changed all unsigned types to size_t (where appropriate) Added the Portuguese translation to the distribution, since Sergio Bacchi's acceptance was received Repaired various minor problems in compiling/running examples Moved in-class definitions of member functions to below their class Added paragraphs about size_t and other derived int-types and about implementing pure virtual member functions 6.4.1 - Legal restriction leftover removed from Chapter 2's introduction. Portuguese translation and `The history of C' removed from the distribution, until formal permission to include them is received from their authors. Changes down to 6.2.4: see yo/history.yo -- Frank B. Brokken Tue, 19 Sep 2006 13:03:29 +0200 6.2.4f - fixed basic-type counting in par. 3.3 -- Frank B. Brokken Thu, 07 Sep 2006 14:04:27 +0200 6.2.4 - See yo/history.yo 6.2.2 - See yo/history.yo 6.2.0 - See yo/history.yo 6.1.3(-pre) Repaired several textual imperfections and delete -> delete [] where new [] was used. 6.1.2. This file was defined to summarize intermediate modifications. - description of ios condition flags refined - description of string::getline() refined. - open_mode `creat' changed into `trunc' (reading and writing streams) 6.1.1b Minor textual modifications since 6.1.0 c++-annotations-12.5.0/compilers.im0000644000175000017500000000205314466730207016023 0ustar frankfrank// This file was added shortly before the Gnu C and C++ release 5 of the // compilers became available. A new version of the compilers can simply be // tested by specifying the new compilers' version at CVERSION // // To check the software using the 5-version of the bobcat library that // library can be made available in a separate directory (e.g., // ISN // /usr/lib/bobcat-5) and an /etc/ld.so.conf.d/bobcat-5.conf file can be // ISN // prepared specifying /usr/lib/bobcat-5. That directory should then have the // ISN // libbobcat-5.so* library and links, and after `ldconfig -v' the linker will // ISN // detect the proper library. #define CVERSION "" //#define CVERSION "-5" // the used compilers #define GPP "g++" ${CVERSION} #define GCC "gcc" ${CVERSION} // options to be used by the compilers #define COPT "-Wall -O2 -fdiagnostics-color=never -g" #define CPPOPT "-Wall -O2 -fdiagnostics-color=never -g" // extra library for the C++ programs #define BOBCAT "bobcat" //#define LPATH "/lib" #define LPATH "/tmp/bobcat" c++-annotations-12.5.0/contrib/0000755000175000017500000000000014466730207015137 5ustar frankfrankc++-annotations-12.5.0/contrib/concrete/0000755000175000017500000000000014466730207016741 5ustar frankfrankc++-annotations-12.5.0/contrib/concrete/refcountautoptr.h0000644000175000017500000001172314466730207022362 0ustar frankfrank#ifndef INCLUDED_REFCOUNTAUTOPTR_H_ #define INCLUDED_REFCOUNTAUTOPTR_H_ #include // Implementation of auto_ptr using reference counting. // This implementation was provided and offered for inclusion in the // C++ Annotations by Jesse van den Kieboom (jesse at icecrew.nl). template class auto_ptr { class auto_ptr_data { Type *d_ptr; size_t d_refcount; public: typedef Type element_type; auto_ptr_data(element_type *ptr = 0); ~auto_ptr_data(); element_type *get() const; // Refcounting size_t refcount() const; auto_ptr_data *ref(); bool unref(); element_type *release(); private: auto_ptr_data(auto_ptr_data const &other); // NI void destroy(); }; auto_ptr_data *d_data; public: /// The pointed-to type. typedef Type element_type; explicit auto_ptr(element_type *ptr = 0); auto_ptr(auto_ptr const &other); ~auto_ptr(); // Assignment operator auto_ptr &operator=(auto_ptr &other); // Dereference operators element_type &operator*() const; element_type *operator->() const; // Get and release element_type *get() const; element_type *release(); void reset(element_type *ptr = 0); private: void destroy(); }; /// auto_ptr_data template auto_ptr::auto_ptr_data::auto_ptr_data(element_type *ptr) : d_ptr(ptr), d_refcount(!ptr ? 0 : 1) { } template auto_ptr::auto_ptr_data::~auto_ptr_data() { // Destroy our pointer if (d_refcount) destroy(); } template inline size_t auto_ptr::auto_ptr_data::refcount() const { return d_refcount; } template inline Type *auto_ptr::auto_ptr_data::get() const { return d_ptr; } template Type *auto_ptr::auto_ptr_data::release() { // This function releases the pointer so it's no longer // maintained by this object. if (!d_refcount) return 0; --d_refcount; Type *tmp = d_ptr; d_ptr = 0; return tmp; } // Refcounting template typename auto_ptr::auto_ptr_data *auto_ptr::auto_ptr_data::ref() { if (d_ptr) ++d_refcount; return this; } template bool auto_ptr::auto_ptr_data::unref() { if (!d_refcount) return false; --d_refcount; if (!d_refcount) destroy(); return d_refcount != 0; } template void auto_ptr::auto_ptr_data::destroy() { delete d_ptr; d_ptr = 0; } /// auto_ptr template inline auto_ptr::auto_ptr(element_type *ptr) { d_data = new auto_ptr_data(ptr); } template inline auto_ptr::auto_ptr(auto_ptr const &other) : d_data(other.d_data->ref()) {} template inline auto_ptr::~auto_ptr() { destroy(); } template auto_ptr &auto_ptr::operator=(auto_ptr &other) { if (&other != this) { destroy(); d_data = other.d_data->ref(); } return *this; } template inline Type &auto_ptr::operator*() const { return *d_data->get(); } template inline Type *auto_ptr::operator->() const { return d_data->get(); } template inline Type *auto_ptr::get() const { return d_data->get(); } // Warning: when releasing a refcounting auto pointer the data // itself is released and no longer maintained by any of the // auto pointers. All these auto pointers will now return 0. // It's your responsibility to handle this properly (and to // free the released pointer of course) template Type *auto_ptr::release() { Type *ptr = d_data->release(); return ptr; } template void auto_ptr::reset(Type *ptr) { // Prevent creating a wild pointer by resetting if (ptr == d_data->get()) return; // Unref current data destroy(); // Set new data d_data = new auto_ptr_data(ptr); } template void auto_ptr::destroy() { if (!d_data->unref()) delete d_data; } #endif c++-annotations-12.5.0/contrib/classtemplates/0000755000175000017500000000000014466730207020163 5ustar frankfrankc++-annotations-12.5.0/contrib/classtemplates/cloneable.h0000644000175000017500000001022014466730207022253 0ustar frankfrank/* Cloneable template class protects a derived object from slicing when used with stl containers Author: Jesse van den Kieboom Jesse provides the following example based on his class template Cloneable: vector > vec; vec.push_back(B()); vec.push_back(B()); Cloneable a = B(); a->(functie op A/B) Cloneable b = B(); a = b; */ #ifndef __CLONEABLE_H__ #define __CLONEABLE_H__ namespace jessevdk { template class Cloneable { Base *d_base; public: /* Default constructor */ Cloneable(); template Cloneable(Cloneable const &other); /* Specialisation needed to override default copy constructor */ Cloneable(Cloneable const &other); template Cloneable(Other const &other); /* Deconstructor */ virtual ~Cloneable(); /* Public functions */ template Cloneable &operator=(Cloneable const &other); /* Specialisation needed to override default assignment operator */ Cloneable &operator=(Cloneable const &other); template Cloneable &operator=(Other const &other); /* Operators */ Base &operator*(); Base const &operator*() const; Base *operator->(); Base const *operator->() const; operator Base&(); private: /* Private functions */ void destroy(); template Cloneable &assign(Other const &other); }; /* Constructors */ template inline Cloneable::Cloneable() { d_base = new Base(); } template template inline Cloneable::Cloneable(Other const &other) { /* Clone other */ d_base = other.clone(); } template inline Cloneable::Cloneable(Cloneable const &other) { /* Clone other from cloneable */ d_base = other->clone(); } template template inline Cloneable::Cloneable(Cloneable const &other) { /* Clone other from cloneable */ d_base = other->clone(); } /* Destructor */ template inline Cloneable::~Cloneable() { destroy(); } template template Cloneable& Cloneable::assign(Other const &other) { /* Assign other to this cloneable with self-destroy check */ if (d_base != &other) { destroy(); d_base = other.clone(); } return *this; } template Cloneable& Cloneable::operator=(Cloneable const &other) { return assign(*other); } template template Cloneable& Cloneable::operator=(Cloneable const &other) { return assign(*other); } template template Cloneable& Cloneable::operator=(Other const &other) { return assign(other); } template inline void Cloneable::destroy() { delete d_base; } /* Operators */ template inline Base &Cloneable::operator*() { return *d_base; } template inline Base *Cloneable::operator->() { return d_base; } template inline Base const &Cloneable::operator*() const { return *d_base; } template inline Base const *Cloneable::operator->() const { return d_base; } template inline Cloneable::operator Base&() { return *d_base; } } #endif /* __CLONEABLE_H__ */ c++-annotations-12.5.0/contributions/0000755000175000017500000000000014466730207016401 5ustar frankfrankc++-annotations-12.5.0/contributions/FAQ0000644000175000017500000000217014466730207016733 0ustar frankfrank1. Too many consts? -------------------------------------------------------------------------- 1. Too many consts? > int compareWrapper(void const *p1, void const *p2) > { > return > Person::compare > ( > static_cast(p1), > static_cast(p2) > ); > } > Isn't it const *const * one const * too much? To answer your question: well, you could omit one const, but it blurrs the intention. Person::compare's prototype is int Person::compare(Person const *const *p1, Person const *const *p2); which mentions two consts: the parameters are pointers to pointers should not be modified nor should be modified what these latter pointers point to. Hence two consts in the static cast. The last const matches the const in void const *, and the first const matches the intention of Person::compare's function. Leave out the last const and the compiler complains, leave out the first const and the compiler will pass a non-const pointer to a const * parameter, which by itself is OK, but blurrs your intention. c++-annotations-12.5.0/contributions/porter.scobey0000644000175000017500000001174014466730207021125 0ustar frankfrankFrom porter.scobey@SMU.CA Sun Sep 17 16:54:15 2006 Received: from smtp1.rug.nl (smtp1.rug.nl [129.125.50.11]) by suffix.rc.rug.nl (8.13.7/8.13.7/Debian-2) with SMTP id k8HEsFqe020630 for ; Sun, 17 Sep 2006 16:54:15 +0200 Received: from smtp1.rug.nl ([129.125.50.11]) by smtp1.rug.nl (SMSSMTP 4.1.0.19) with SMTP id M2006091716540904671 for ; Sun, 17 Sep 2006 16:54:09 +0200 Received: from mail3.rug.nl (mail3.rug.nl [129.125.50.14]) by smtp1.rug.nl (8.12.11.20060308/8.12.11) with ESMTP id k8HEs7ba029629 for ; Sun, 17 Sep 2006 16:54:07 +0200 (MEST) Resent-Message-Id: <200609171454.k8HEs7ba029629@smtp1.rug.nl> Received: from by mail3.rug.nl (CommuniGate Pro RULES 4.3.9) with RULES id 26722890; Sun, 17 Sep 2006 16:54:07 +0200 X-Autogenerated: Mirror Resent-From: Resent-Date: Sun, 17 Sep 2006 16:54:07 +0200 Received: from smtp1.rug.nl ([129.125.50.11] verified) by mail3.rug.nl (CommuniGate Pro SMTP 4.3.9) with SMTP id 26722881 for f.b.brokken@rug.nl; Sun, 17 Sep 2006 16:54:07 +0200 Received: from smtp1.rug.nl ([129.125.50.11]) by smtp1.rug.nl (SMSSMTP 4.1.0.19) with SMTP id M2006091716540704669 for ; Sun, 17 Sep 2006 16:54:07 +0200 Received: from HUSKY0.SMU.CA (Husky0.smu.ca [140.184.1.100]) by smtp1.rug.nl (8.12.11.20060308/8.12.11) with ESMTP id k8HEs5Hr029615 for ; Sun, 17 Sep 2006 16:54:05 +0200 (MEST) Received: from [140.184.170.51] ("port 1263"@[140.184.170.51]) by HUSKY1.SMU.CA (PMDF V6.2-X25 #30841) with ESMTP id <01M7AU3VD1VW8ZFLAU@HUSKY1.SMU.CA> for f.b.brokken@rug.nl; Sun, 17 Sep 2006 11:54:04 -0300 Date: Sun, 17 Sep 2006 11:54:04 -0300 From: Porter Scobey Subject: Re: java_cpp_keywords.html In-reply-to: <20060916171615.GA16340@rc.rug.nl> To: f.b.brokken@rug.nl Cc: George Danchev , Tony Mancill Message-id: <450D618C.7070206@smu.ca> MIME-version: 1.0 Content-type: text/plain; format=flowed; charset=ISO-8859-1 Content-transfer-encoding: 7bit User-Agent: Thunderbird 1.5.0.7 (Windows/20060909) References: <20060916171615.GA16340@rc.rug.nl> X-Spam-Flag: NO X-Scanned-By: milter-spamc/1.4.366 (smtp1.rug.nl [129.125.50.11]); Sun, 17 Sep 2006 16:54:09 +0200 X-Scanned-By: milter-spamc/1.4.366 (smtp1.rug.nl [129.125.50.11]); Sun, 17 Sep 2006 16:54:07 +0200 X-Spam-Status: NO, hits=-4.80 required=4.00 X-Spam-Report: Spam detection software on "smtp1.rug.nl". Questions: postmaster@rug.nl Content analysis details: (-4.8 points, 4.0 required) FS_GAPPY_2=0.241,USER_IN_WHITELIST=-5 ____ Status: RO X-Status: A Content-Length: 2373 Lines: 65 Hello Frank, Thanks for your e-mail. Please accept this reply as permission to perform the two actions you mention below. To be more specific, you have permission to use my file at http://cs.stmarys.ca/~porter/csc/465/notes/java_cpp_keywords.html for inclusion in your site at ftp://ftp.rug.nl/contrib/frank/documents/annotations and also in your Annotations package to be offered to Debian. Furthermore, you may use this file with or without acknowledging its origin, you may modify it in any way that you deem necessary or convenient for your purposes, and you may pass along this permission to subsequent users if required. Best regards, Porter Scobey +--------------------------------------------------------------+ | Porter Scobey | McNally North 104 | | Associate Professor | (902)420-5790 (voice) | | Mathematics and Computing Science | (902)420-5035 (fax) | | Saint Mary's University | porter.scobey@smu.ca | | Halifax, NS, Canada B3H 3C3 | http://cs.smu.ca/~porter | +--------------------------------------------------------------+ Frank B. Brokken wrote: > Dear Mr. Scoby, > > I am the author of an Internet-published document called the `C++ > Annotations', which have been around for about a decade (currently: > http://www.icce.rug.nl/documents/). People who want to have a copy of their > own may download the document in various formats from > ftp://ftp.rug.nl/contrib/frank/documents/annotations. > > When they do visit that ftp site, they also find a copy of a page I downloaded > from your website: > http://cs.stmarys.ca/~porter/csc/465/notes/java_cpp_keywords.html > containing a list if C++ and Java keywords. > > However, I'm in the process of offering the Annotations to the Debian-Linux > distribution, and by doing so I think I should obtain your permission to > include your html file in the package that's currently being built for Debian > > In order to avoid embarrassment caused by improper handling of publication > rights, I'd like your permission to: > > - Keep java_cpp_keywords.html on > ftp://ftp.rug.nl/contrib/frank/documents/annotations > - Include the file in my C++ Annotations package as offered to Debian. > > Thanks in advance for your reaction to my request, > > Kind regards, > > [Cc: George Danchev, Tony Mancill] > > c++-annotations-12.5.0/contributions/GGD.algorithm0000644000175000017500000000314614466730207020716 0ustar frankfrankFrom d.j.heijs@wing.rug.nl Tue Jan 30 02:10:13 2001 Received: from oosix.icce.rug.nl (root@oosix.icce.rug.nl [129.125.14.80]) by suffix.icce.rug.nl (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id CAA11404 for ; Tue, 30 Jan 2001 02:10:13 +0100 Received: from dep.cpedu.rug.nl (dep.cpedu.rug.nl [129.125.28.200]) by oosix.icce.rug.nl (8.9.3/8.9.3/Debian 8.9.3-21) with ESMTP id CAA25169 for ; Tue, 30 Jan 2001 02:10:15 +0100 Received: from skylos (client44-109.kabelA.oprit.rug.nl [129.125.44.109]) by dep.cpedu.rug.nl (8.9.3/8.9.3/Debian 8.9.3-21) with SMTP id CAA31441 for ; Tue, 30 Jan 2001 02:10:13 +0100 X-Authentication-Warning: dep.cpedu.rug.nl: Host client44-109.kabelA.oprit.rug.nl [129.125.44.109] claimed to be skylos Message-ID: <000701c08a59$d376baf0$0201a8c0@skylos> From: "Dirk-Jan Heijs" To: Subject: Gave ggd functie Date: Tue, 30 Jan 2001 02:13:16 +0100 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 5.50.4133.2400 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 Status: ROr Hoi Frank, gisteren hoorde ik van een vriend een mooie functie om de grootste gemene deler van twee getallen uit te rekenen (het grootste getal waardoor beide getallen deelbaar zijn). Hier is hij: // Copyright by Gerton Lunter int ggd(int a, int b) { while(a ^= b ^= a ^= b %= a); return(b); } // Copyright by Gerton Lunter Gaaf he? (Heb je er nog leuk commentaar op?) Groetjes, Dirk-Jan c++-annotations-12.5.0/contributions/README.makebook0000644000175000017500000000262214466730207021052 0ustar frankfrankThe following recipe was provided by Jurjen Bokma (j dot bokma at rug dot nl) for creating a neatly bound C++ Annotations book. He gave me one as a 2011 X-mas present, and I think it's a great gift. Thanks, Jurjen! The recipe then, is: - gunzip makebook.sh.gz - Call the script like this: ./makebook.sh --t7 -p2 cplusplus.pdf (t7 is for 7-sheet signatures, see below, and p2 is to prepend two empty pages, which you may or may not like/do) - Have the output, cplusplus_book.pdf, printed. For normal-size output, you need A3 paper. I use 60-gram paper, so I can keep all in one book. Print double-sided, short-edge-bind. - Separate the printout into bundles of 7 sheets. Don't mess up the order. - Fold every bundle neatly in half. - Take these folded signatures to a book binder, e.g. http://www.boekbinderijerends.nl and wait a few weeks, or try to DIY. Background: A bound book is made up of signatures, stacks of a small number n (e.g. 7) of sheets double the size of the book's page, folded in half. Each of these signatures gets sewn into the book casing. So the A4 PDF being processed must be reshuffled so that the pages are printed on A3 paper, in signatures of n sheets formed by 4*n original pages. That is what the script does. This results in an A4 sized book. If you need other sizes, adapt accordingly. c++-annotations-12.5.0/contributions/makebook.sh.gz0000644000175000017500000000502314466730207021144 0ustar frankfrankbNmakebook.shYmWK#ȨII=FXA&f 1ߧ{r,ѡ^jq cZC1Q IDO4ȡ)t,\/Bw9x+zҡߩ`44q"ě@D z%~{rb2b]C'loOJV37jNX "M;#!}C0rC5t=,a|xQP]ah\/[g[FZ6eO[I'ѽV O1^ϸ5S9Ijω?1]8" zm"QL\FJt~EجW塻^8o[!1svx0qP^p#$ClA濧nK;LCw30ߢ!\)Y.477Bxa, #tcCbI'>\/ =})hN8f? ay@׉͛z0^yAI^ݑ8KMꛎo~6zrǻAnɶҟp(.Wy kPq^J/d辂QH6*H'$cvߖ_; Y=lt-;oto=> 'P&Su2D|ع́C;2Ǚ -[L1rQOX<%R )WYQ8B|uب](LW;ê}Qvyơ$n}عE^7k0J,ƅ[`I@j_avR`+SLrEJSB2xo8LI~< Jz3Y9JI87dhA"4KcTbK,1x vDm.ezbH\9gniOG=(r$$2&g,˂@"$ݤD%{&x<="ȝW1R XI+O!&df.mY`841j%[K L% |{U.4đnWށK폱1~X1 s-v[;!5&4藃5+bAN {+Zmo ~q}fByYٻfjjĹ% DrhB)C6A`XPك(6Zd{'<8m2Өl= *ӫ9Jl]4VOokd'z%ov< ȪZkp蝞Q?P?9 PԍdÆ Nі禌h2P VI'$ddzg7i[,įy&72gӚՃ4]F[ئ2n~dRc.o|zt‘>68cjKtpTH_B2"b쉲N].w#ܒ F$j۲+3CZ䶚yYW \R=ʨt9lY<_|m%`X4t3SH&ޱMn}Rn?}G+LRBAAEc++-annotations-12.5.0/contributions/sator.proton0000644000175000017500000000242014466730207020772 0ustar frankfrankSubject: Thanks for the great book Date: Tue, 19 Feb 2013 03:26:06 +0900 Hi Frank, First I want to thank you for the excellent work you've put on the C++ Annotations (v9.6.0) book. I read it to refresh my knowledge on C++, and I can really feel it's a great book, especially for someone who wants to get a deeper knowledge on C++. I'd also like to tell you that I have converted the HTML files into MOBI book. I did it so I can read the book on my Kindle apps, and I should tell you that the conversion works without much difficulty, with the result looks really great on Kindle. I don't know if you've tried the conversion yourself, but as a token of my appreciation for your kindness to share the great book, I'd like to share the OPF file I had used to create the MOBI version. If you find the idea for MOBI conversion is good, please feel free to use (and reuse) the file. (It's just an XML file containing the metadata for the book, which you can inspect and edit for yourself.) To create the MOBI book, you just have to put it on the same directory as all the HTML files, and feed the OPF file to KindleGen tool (which is freely available from Amazon). Also, if you wish I could provide you with the MOBI file. Thank you, and please keep up the good work. Best regards, Sator Proton c++-annotations-12.5.0/contributions/java_cpp_keywords.html0000644000175000017500000001514214466730207023004 0ustar frankfrank Java Keywords and C++ Keywords

SAINT MARY'S UNIVERSITY
Department of Mathematics and Computing Science

Language Reference Material

Java Keywords and C++ Keywords

This page contains a table of both Java and C++ keywords, showing which are common to both languages and which appear in one language but not the other. Within each column of the table, the keywords are listed in alphabetical order.

C++ only Common Java only
    abstract
and    
and_eq    
asm    
    assert
auto    
bitand    
bitor    
    boolean
bool    
  break  
    byte
  case  
  catch  
  char  
  class  
compl    
  const  
const_cast    
  continue  
  default  
delete    
  do  
  double  
dynamic_cast    
  else  
enum    
explicit    
    extends
extern    
  false  
    final
    finally
  float  
  for  
friend    
  goto  
  if  
    implements
    import
inline    
    instanceof
  int  
    interface
  long  
mutable    
namespace    
    native
  new  
not    
not_eq    
    null
operator    
or    
or_eq    
    package
  private  
  protected  
  public  
register    
reinterpret_cast    
  return  
  short  
signed    
sizeof    
  static  
static_cast    
    strictfp
struct    
    super
  switch  
    synchronized
template    
  this  
  throw  
    throws
    transient
  true  
  try  
typedef    
typeid    
typename    
union    
unsigned    
using    
virtual    
  void  
  volatile  
wchar_t    
  while  
xor    
xor_eq    
Total = 40 Total = 33 Total = 19
c++-annotations-12.5.0/COPYING0000644000175000017500000004310314466730207014533 0ustar frankfrank GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. c++-annotations-12.5.0/html/0000755000175000017500000000000014466730207014443 5ustar frankfrankc++-annotations-12.5.0/html/annotations.gif0000644000175000017500000000772214466730207017477 0ustar frankfrankGIF89a{!!!"""###%%%&&&+++,,,...///000222333444666777888999:::;;;<<<===>>>???@@@AAABBBCCCDDDEEEFFFHHHJJJKKKLLLMMMNNNPPPQQQRRRSSSTTTUUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^___```aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnooopppqqqrrrssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~!,{ H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻx˷߿ LÈ+^̸ǐ#KL˘3k̹ϠCM4 0uװW D-چ70`뚨wnta ޼ҪW)7{;O{Jۧaj襷<_X_$GAב)T%R@ʇqY'P aF68Ryف!pQj*}IH^wwA֢{8{>zDy":U^Baw(xߒ P.H%Z@&"w[rvdw##a,k"AevإF@}hXJDbl$e xIt~*HZ鐕\jRjQ[ @vP&kB:+scrwl PD+5,M6dS.(Ftd,W™gum0&nok:s { Vnݾl [k [”}iqE݆t*رV^iGino-S¼u/e(wʳ/ [* a]/ۜ,kgsI]of~lQ mD*#VN ʦr,puW=7Bo8H_ߋ#wrq=A x؄=.ox%]Ћ&f`:7"XЉ;oW `$f 7'﫳gNvɶϦc۹o ߽ zdsL(M2 u ۥH>n{;UAX(|` U ЅTaȷFoēİ` L|h<񲇺p*7h uR<*+7ɰP,JmWטYj=_qw͆7v虲~4| Hl8KͿ!Dp,d)ga[ M?S;(Or;^^ 8EA~Бe4R.K8H*:#2=vp{~J$MhNlڞ٠MjЖ, IR'jO,Tjqq#+w*dzE'wK`>vD!{uTh0kZO|3+eBF4P(?;bzxӎP*Y'~O MsǢ:?i‡Sa si`s7V:YS_J˛@%a9sQyqxy.e$XRj1U"aeՏye,ETL*ZzP!V!=_qBW12{E>)ao$py􏬘U"&8p{[j5 [UvU+ s /pli J["CϾ߁W!&`!gv 0ŵ5tʢNn!e {16a`ΡA/ (uL0m-j+c8^#ԫmIU.єHI2 GA.(gT'M8"Iaٓ?S*L ii4 -YI^"Xq&(פgl}5Gd?C sfчFt!E@[Д뜺;WS Pz'mOj4iy[Mkl#w^MbNf;{WM%g5d`}{#l\ ,LFp+lQI"nmoIIДfY&̑ISF 94,o3im"ȴWsۗW)*Eŕub=؀/zKj.e!3ǙrT"} <<Ȕsz9Dr>sA77[r{5VC^4uIG}76MUu"wvAEkZJ ڣ{nodKzqPX=4kxmE6'^C~]DTh,mŔ+^j.ĆGtn5+Hՙ0ہjr4x:=}ޟB{uNWNoҪ-=zaЃs|Ko]ZAWfOtvp#V&9tA҅qOv"eCa9BV31򀖳*,FGe#uG>!A5Ve4]q+u"x[er2%2XAZ҂WWyf;Xa:DhBHbesK!D pr|dd.S@ȢZK1##`M:tp"Le5G*kV_#WvR;TPXbu;V'@X>E_(2%S4O #ug'Yh(_Å?qeX}'toз$W2u(H*hHC$U1B|؇H6[X'sHi38M1xx3߲?hhBu̱qݸ`U҉Bu옍*$w`JP:X#"0؏(Y*$S5[v(YIqhIfu#y Y5x?-.ᆊYQhűLAXFOwF9.&F(H[4H T&6oOҋu~AޔSӓSPgIA'ZL9/5E^c68lQHScUb\#_^]a%zٗ{qQ!;]wg-"X}G|[[ZOl[{I^5~G#b!*^s8x!J"4mFR^㛩Yb֜{#uhaVSffQhiFyx8ĞI9Mh1RG'G 6GwrH-X]7r rV:X**ڢ.02:4Z6z8:<ڣ>@B:DZFzHJLڤNPR:T;c++-annotations-12.5.0/html/first/0000755000175000017500000000000014466730207015572 5ustar frankfrankc++-annotations-12.5.0/html/first/datahiding.gif0000644000175000017500000001621714466730207020364 0ustar frankfrankGIF89ay """222333777888;;;@@@DDDPPPUUUXXXfffqqqwww!!4 Image generated by GPL Ghostscript (device=pnmraw) ,ydihlp,tmxypH,Ȥrl:ШtJZX7PxxL.zn|N-y?|{С׃~ ,h(0> f-0{z.> J ̛o2vR &AD!(VuqK? yR@:  a`f}+ƨ4XҟB5q0OAX}klwa=& r5&w23H~k`YLȀӠBI {pPu}笕:w@ y !mDxZa \0 o]ŗ"ˡZLrG-X7^z0l@f8O lGf`>4@6O= `=hAuUgA77uyAA|,@ bфuDE68@۩yTK] R~00319E ه|G OhJ=V9GUMOu#-Pm܃AC ]drCgO6D%T[ ik&J"ncmΩAIgUiL IG2EKfɇO'* z&h_e |!!R~ n0e$55 )g maQ0AlH#P tT"ⷬF+ 6EQ PHË7R 9# !TFOFZ$uIZ$&7IB (QQP$*Wʜ\e)cIKIβ.q]"sE/I `;S`B <<ێF5ͦn+dUlm(@" ND('jx10Cp)u窱!&-1,P{2Ph* p,^ oP co!MjM(m욨"דW˗@62E&sEjʝ*H\`@z6ёzX"B$mjUQ;(ґ%[]'6Z~*8 *@>Fu'0T/3^8Ɠ)'KX(: eRPDo滺%HhZ bNp͞(elKۆ= eq?9$4C09->S6s3?ϸ̃=C?k$0:'V7ω.uo=]vv4 gmiOaɂTH1>zOƿ! (,Ȑ|((oyEb~Ub:#A=O/x9_=#z[^v7}14}k'o|J> GC>m|Gڿ4,-0~2߉\L~#b] 7_I p B*LzW rCXUQ @p*?6 # R1#*SR+UZ$!?R"QA">_Mz'DaC**\)+b֢]ޡC!%XKQ(|( 3XZ,a*jItU <,3/CE"5v/x|G 3(_h}PSR >33?*RpmKo}'}UXO#g!21p?.OVW0Tsc֔׈(٢b<2A* =mR+O0K|~H]Ȍ^;+bA2$?p2H,6X40:Q$Gv"aTdG!GD>!8l2{FdW"|q &yڔВ.p'@594w8 :@BI7YwI D9F H7PV)t=IS(NٕaɒcId/akzJ} z* Z=MJkJъNe L/ͺ~I:*+ݺ*Z% Ji)PJ*y[-0Z 1 $xU+LjJfԕ@` .l4%NfGqG0cOu$=.Հd;[+PIVU),#0uXj4g\00##EXѓf+ fkz0uCp@1(Bl!eΊʘXX%!1w]1X<"-ɻ\ -yO~y" Y]zIV`dk kڱvf D:B[Kl̻, zkBx UƂWX|j|5_uCEXo l ߂M fMu"ݳUk!",o ;-. -"'L;YB/2VE;>!|utSadwk@x OTE[_} ޫ3K^]`̼uaS^*]&xw4X02] e0M NFl^BFV Q!CvU=,ߒP Vᄐg-=⌎2c.FX'rT[#' A`D]q857f 9elO'pK'ݨQ=8"~_>D%*)-N@Q>0]K6 ȶW!XZ{>D5Lv$`!cj3|\^kk8'C'!Pz>j2M6 U'!JQaI5\\&VSZn-Jx. ] %^|w+jn WŪ׶-jS.:Js z fߴx вrE;9_$TՐ*oӜOբ?Y֨?M x pO{+9v?Vm o " qgИSt" A"TƐn+ "DuF0a8rߘ. 0 l4EP`(i5n\5Hڨ 5r Gj5phL"uțXmrz1*XR@̘FFD CMZKC\ @΢Meأ DW@P1rr@pž€I֍p%RC!7Lo^ //J)@F>vFbIuoC.Ao x A#Ae+Bzi$!g.,R^,a-Rׄ#;ԑiذ`=( *\-ɖ5H*PKepw ,U <6ZVAYA="ҡ.m$Bo_=^DA{6( 0"ՁmW7tV/Yڷ7w tYWءY!164X8OJ{l'aQ{C5Gg 8x X d+܇mj٠t6ap_cρYMiqu|fYl :\34rI"c"r߃Y2biI(HyW̜@m fD$*̵e`y#C׋gTx*狀4KyY ,?JL 9xpVAcaTlmj JZZi*ފ@PT*q"=ڐARjLy Ëai"8)N:.Gñ܊*! D'Rfe _ʭ*!&.薪g@WhҦw-bndOAWbbz7c宱0>nI.ЕfEDt} "|9S7!v`Bf@ZXoTҀ6ASbYz#ذrM Sv_@^STc$]*<%y-'tN|&u({|8`P D9=.FA Dtqu$=cؗwKt&?B.[a<'܌f3(: !Y8 % <&12XX i::O|`wB. XX1,pO@֌VeE 18xdXOp,BX@ڐ!X)O 2>#'C/!1X,r^"K1cܢӨ5Nl|#s Mv D<D)Ak!E2̠##)IR򐐬$&3M$(CHO<+*|%,c)YҲ%.s]򲗾%0)aR:&2e2|&4)iRּ&6MhZ%&8)q<':өu|'<)yҳ'B;c++-annotations-12.5.0/html/advancedtemplates/0000755000175000017500000000000014466730207020127 5ustar frankfrankc++-annotations-12.5.0/html/advancedtemplates/concepts/0000755000175000017500000000000014466730207021745 5ustar frankfrankc++-annotations-12.5.0/html/advancedtemplates/concepts/nested.gif0000644000175000017500000002030714466730207023720 0ustar frankfrankGIF89ah          #&*+-0".3& !*!#*%).'(+)-+*.4 !6*,?,.7.064:;7::8>G47"=D3>B,@F-AG+LU3IP9QY3\f?[d8epELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km,hq&&/1 H({*LjÇ#CgÈŋ3jȱǏ -2 e(S\ɲ˗.L4e8sɳϟ@ jdf&T*]ʴHP&4Jgц6jʕQLH{駨dZz0ڷpr nP%{TͽD7a8x;=up#7u 6佉JXYw vNrN{.韻3]lP{Vm}(>Ko+ -DQIs'ҁϚ4g/F7S!dV 7 N*$~gt.Ly թt9-s蒳ߡq!"|HD,Um38f`D xQ@BJ Id`)DJr:o%(M27' J 6|$ G)RBRd6JFD2jI%qHI\p*q]’9NI`*1)˧ҕ&c'L3012 *P IP9v<͙$@} X}C}cVf܆f_'u]F{7.{{n{ x(pz4;JX}(xZvhx7pDŽQ]ڵ|] wx9}~'~g_~W~q` 7>Ѓ7xx~aЃ7gh~ApGJXxH 5(ZF}f0H & {H(Aȃ>G8EHe8 ɨaƌ Ϩڧf:xthqkXpѸ؃X};H]8h@' )f  9w`e ّ )DW Az(eXp"0y 2ّ4 68ٓB9 D9Fo&`R9TYVyXY9V@$Д 0 Q &)-*Tc)sefZ`{{I%s 8E*p9Y4Py gGh9)UhwٙPUřI 9UFc SUaaYhy 9)v) ʉXٜƜ҉bKyUۙW9TYW)X晞ưU䀞T`9 j g퉝 J٠:T z*00R#!*Q.0G<6*Z8Z:oգN@UBZDZEuؗJʣ,YɤTJVVXNo_.exc fgIo)eb0X\X{^{^f]ʦ1o'}g7F'~7~;e 'zhW} e؁Y6؁|z,zU0Ux6h}rh*~D*ZzZֆoej(u؍9٬ZVxv菬y ) >Z% |J' PzHQ*DD z8 C{wKGtpT k'Ա;(u*k(dltLaW4HdAkv>J{-[I @2t"8d W-,s"H 'Y˵B,}B7Ck#24"Rh:RR &[hHR:ƶOp;[59+S&8"o""DhaᴍQ vvdCjv+Sp+*6;0/۸ Д 2 /F[/ZH5k;k\5!RB2*4hj&))"$A'>s;rΰl PeaCMR n"30aNH [u kGm[b$k>!%L#'tgd*9N:B7:IVm..0.t=@QI 7m9ޠ;r|6 ZuGվJeL^Nu_?AT^WYqYRUka_>ckmuR6[M:ïְؐh|~~~voZesJ} fͅXezze޳(>꘻׺ّ~wUꈤ-wڔڊן {zɎ ۾خ j~8}۸=xj׍Z~oW}>ܺ}mОeH੸޷}. oZvV$h,.08 [68/:b@=_D_(/`JGN_6TQV&PѢ1b?/^>glnpr?t_vxz|~;c++-annotations-12.5.0/html/advancedtemplates/multibase.gif0000644000175000017500000001461114466730207022606 0ustar frankfrankGIF89aJ          #$%&')*,,0"""+).;()>++333:7=K::DDDHEMR@DWGLYIIYLL]LRUUUWS\gXXfffealtdmto{wwwp{ww}!K,K $1' Ÿܭ1J;ᚦH H ?*b\#JXnK jȱG/9!œ(SBHRRƏ0cʜ/d˛ ɳgEz8I6*ӧӧY.]4ի3N:)ԯ`Iz*ֳh j%˖װpÎm;lڻxݻmܿNݵ|G Jt 5eh+̈!0C~m #Wk@Q͜5Gs(yQsr6I֡E!H]h _ FHLCD55&܁T 6Ip9!0!&Br!":QXzB|A !}9PF0Ce$?3Y!p0 9%btJ@BEȰa$C B#ăϽ CGÕCZ0QS&O*9(0 PiD"(p>JAoܗyj J ɖ؀"B PD+ i #9GT{-9G (WE|6&>"h) 1"@e&Ppk>{O35(pj3#9bh-OBRW%]*3KFsD=qnl)>g 3 jF̰jj;dz0?5rYΊ2ۼ@'(C.9I|;}9(#Rsno-0 +<XMj mb>x}WE4,Aȡ> uq(+袧QgAyt6O"/GG`%#PuR#6`Hgxa7* "8C@ HGMx`bɠp\90!Y:)9E0@i;ާ:đ(U _H.MD S$j7(pG⁜WQD{(,xH+`@p}G0_dn $UI//…a`CbcfE&6Yej~:ݧ49Yt&N~ꅞa%>}ބL( Ж4CߩЊj C!N'F3zr4(ECR 1IR|)L!әNY)N=i\jZRuF=*S05'N}jK*`$`jLՐr*X"քܴi9+ZmAյ<%+\*׹'؁`KMb:1*z@Zͬf7z h3;¯M)" "E´P܆p ;W9r{2w}tk6"ͮp]C`5w;nzޝrwm|Iwk}{WpGݯ'<gT0Ak^D ^WJ,b`tqUoK!DNRt$+8aT *,-\sBe3'Ԍ6g#a 2_CtsgՅpZz.ġTTmeCOZnc7N{ӐŴ[A@ ԨNWVհg jO S`uϜk]ם5+*D밑 _/;v  -վ6fnw$Klk>nwT- e6ݓtۃƦo'^Ex1D;8QӜ\aGw4,s *;/pł(d! Qn'647Pϲ*z~U4MjbSt9N(8cx EAt}R'%.G~%R{I@R<9d61%VR7ɔD<&| h/%wCy7d44yT2AGAgsBAr2F]J=@wC2Px8o*H6SR$9)5*374C7`1wH5yLJg ѕ2F)ne8y>ʴ,O97yX!9tՙib?ኳWYb՛@yIl !@y)f̉ɩPyؙaY E嶝iv4Vy)A 7Ja0  * -P 9pVZVj֡ fkbhPP&E Ƣ6Z.fg9fx v֣[;&%Jif9mJZbNQ 6QfTZ[$꩸ 7 PFz[BYuJZ8\(z%G,@ڬ:Zz8YƺvFيĞ*:Rjܪ\pz\ZڜzV[ٯ Eg߉!ư>Ffݚzl oYuq(p#4#'Z*+1! |(|4w!U"=g"?p,rY% D`Ftftf&mBuru=}y(3."+rI/L/I)u@!|ӘD!|WRBJ{gȗ"0wp,wu-w-]xtuSvv?Pz2+?vQ*7DDa0`X<:)@)FF)t)y=2/ysz2ziFcU,ׁ609hT|6AԈ$]`GXA岄I "d%T,[XLcB:ྚǸ2R ÈĽKŠR?w?rIH_VܔѬ@0E%æ%aGsiԉ(C˅$|Gq0N1:  ;(hIc;t)i͕\D+[[`0ɲ#"@Gp0S ,Vp.UCaI3GLJwI1#,lD+Ь 2w@r|~yYUU Ջ!LEs0Am/}=Ʊ&AC;RُpBR}Tm Ma<(1۴ ڵL`m=ý S]]$܇ ]W{I %v5TaڷݰyZ] >+=`V >^ Jl]H, ZEe~ Zթ&'N`)^cd0N^/N\2^|z%:~^9NA! F_\45:jP7T> W^V.Z>`Y aaJ_^N6攰h>aj^\gr>v>ey~nG|/FPN~a^_Fa9>d-^` 0ꤞW~p.š5na :욵~e>b=$N/bٮT^}hޮ^x1h~﬽Nt?/6eތ Xz&з+)01*ѷ[L0 "){KJ22P?j`QK7;vH5ȻO <@#FHV)<") 9/17+ayԋԃ )/ D{o&ݼ{ċ;7=ț[ܻ{\=;m>˻?k?O~ H`\`ԁP`:7N^߁n!gbbyvHb,}b؍hb.n26#@c>dBIdFdJ"N>0RNIeV^eZne^~ &PIf7afj&eiW ;c++-annotations-12.5.0/html/inheritance/0000755000175000017500000000000014466730207016734 5ustar frankfrankc++-annotations-12.5.0/html/inheritance/hierarchy.gif0000644000175000017500000000304414466730207021402 0ustar frankfrankGIF89a+++:::HHHVVVeeesss!,`$dihp,tm| Ȥrl:#0Zl pxxL.Un).zN~?vx|%~bo}],g.eik„f`ba̔pű cgܖyd_   ^HG 92@xAz AP/f!PD rp~ \$2nb:[2#s(9F .B'[E8u*Uс^(| P $@pu!%u (QؾT6-ȱx*iޱM" p5q?tdƔ+yfF9LhH&s0իvH۸sBo ѻxƓB9&Σ.ֳ; O+MϾaߘ~m侔84N_A .֠ 8߆84x0ۉ(&Khm0F09ꘋR>q$$FFBV~"YQeCr Jyǖf5el_injm9Fvzewɧ@)ۜ)Agh"Fi( xр] ؤ-"v)%Αe3J F:^pB,T$v*#ެR=CO6$ꙗ?IңQ*YZ)d=ܚ",PQ;(v t AF}@VW6ۉAD{r.`4`@Kn]L&٪" Pd ٞ!@􌽠k hs\G Up2VoE3Ĥ.0Q+3G>E\<^- ˌsfzg>Y:l'ڹW:w;?V{[yCzC93|h*Ji=C!#"w/~$/beD.O?#j(29|r"(AP ] b}`!h4*{"lg yi Cp/\!ZCdnG< j 1:91q;ItH"TDb'0dnY^+`L1:|݊Or9)ug ؎b*W+#Fs&@%IbxQ?_~r|0^G=Yle \ޣb,3y[F?1]^h"o?Rť.A* v!}z ȝ [e^ERCBXÅ݆ $Ma}8b(nhbV+Yƌ4r2=r;?BdFdJ.dN> eRNIeV^eZne^~ fbIfffjfn grIgvމgzg~XJhh.h> iNJiRgni~ jJjjj kJkފkk lK-xñA栬"4pH12#_2'۟2+2/cnzW`W8 id@ڎC`!@ hA ~PaJЁaOA z l0>ǻT 9x-Th$ :\x'AP*/I{+ybHE1KhL=5:kz(u~$xY1t"YIRrYK$呓sd&C)UJ[%*E$W,_F^rd ^:/0-PKMD&dǔ&xgQLc7^~ L(sfsl; xs=|s? Ѐ t-AЄ*t 9 шJtE/ь*G? Ґt$-IOҔt,mK_ Әt4MoӜRo|bF' Q} ژ6$%hpۙ_!NuT*U6SjX{U. jjVQHP:EU<,VW_[ X9˛,1cY&J.5,g,^Y9-j kZ= ㍫h+Zp6mc\obSlR{BDs:]PCYi=eSUb5N w}w x.U;c++-annotations-12.5.0/html/containers/queue.gif0000644000175000017500000000227714466730207020433 0ustar frankfrankGIF89adర!,dڋ޼H扦ʶ L ĢL*̦ JԪjܮ N6Z&8p)9IYiy Gfx *:JzJ&P (J8[u;L\ %l< },M]d ]-~l~?J^?.kO/@z (0>@0:Cč(n" J<2J4r|yeK4k)͝+G N $y-94燢Gy&3]O65ZUǫN}N3#םYf`:g`ۺ*mZpK.nW݃S]ׯbO;8$^yReˏocHnHf>JɁU#d&N9& Bv4vǵDe2F3nrx9'WЇSa2 ~j%7+s{^}utbtr֜|卧ށՆE؞ X'o}Z~:깗b6آ ᝉGjv0"=*c"A"2);x$zhcQx"|Ȣ0RQ!/)bݔTHpjA~YOW&g&G|'@祜 F(MQ| *z!#a1ɡ݀XA}2ziク7&BaE]dVA.ܮck&~KjAκ-.m~kʴn+{m㒻Vޢ[|r^U,-[뮿  /spoS.UodRY1slp&1ʵr<-L 133ͩ|s89 =tCKsA 0I;tMMuVuACu)zaw5ٿdwPMurMwv wzw~ xNxx/x?yWzPAڎG 9 K@|+ʆ U^9}7;z"rm+~Vʾ%/z;3>:*_ȻGZ'jٟs>,b=b̓>>Oߏ p,P;c++-annotations-12.5.0/html/containers/list.gif0000644000175000017500000000234314466730207020254 0ustar frankfrankGIF89ad!,dڋ޼H扦ʶ L ĢL*̦ JԪjܮ N xgxH8PXxi@biH Y:* k'Zikz{J+kLG[{ڻj{) -y͖Lk,m|9-]-/_o~N<}~Bڵ}Zh0=|+@q01xcڨ̙,!IW7T"'eU1g/{@ CJ4E)ԀSNC*VYZ:+b)k{lۺEKܹSѽ+PZ 8 > ;~LXƐ+[.,U/{ @3ʠK7ɴję7/%:vdeFխ]6mU JylЋKLuսv٫2wN1H?[|$dNtU_;X91Y.D 5a(5aV_Db'~ȅT 8[H`+:#f0 !=hcx<IdLF҇d`/vM&V$qSRW-jyWy]*d2if*[ry&iBS։#xӛx~y %mJ)z'm2Y ~6i}yj{JJPj{x+Κе(x+h$Y.Aì|Yz# &l7E+ Ύϰ(v^~rֺn^r oO׵ܦ+yj;Z:2n"mu 0(;>oX7S/… 5b1B~ܒջpG )%'8cdHA21;5/i24=e0jcBkT9I:\XtkbÔK,Zk m.M]c:Wn8+1Z>xiČo0ɔ+[9͔R9љ=g%:沦JV ;vcF={ݢYClp͹?nȑV0.)ǟCWj}usE>{=k6O/[tI MZq`",^7.M4)=ءQXᅉ8bca↉ACƘ EciiՎ78v42D^ơCS/:$fFyJVYm%QVOx%feYfޙ8iqY̞|Ι~'m?h5#`rh6 ()mVץqv4s*d2:j2lbjJa z(k"*hklVp.,uuNlR-JޒYfn[nfe&iW6r/[WL%'DzC< 0C;k[LB a<*:KRƋs,[op׾lk0Jq7ϜtMxNM)A0[GFRf?ʲuSݬ07 V wL9TŽd枧(mi7s%G}E그NMNy]REM8S.O¹O»Wq:dS:0eckp~)9osƈ'pL+ȼt1[ |NQ "'- !Cw|C/Ph`I\ g0\b0Ҁb, h40T'h[;]yc=820~BV"񑸈dHHI@1d%4H v,k'%/Xe\JT^r %$jYYv)]D/pb""V`2"LdF@f3IA8LQ-@l6L9-sʤ29)pi'SGLy24> Oӟd(<jL*u'C-Z{^T}(D:e8hIz҅fԣ}ȶ R3hMIjN4PpR :@{"U7hAjCp0L]RU2QC ԪfUL<ʼ4VeX*VW=ב浩 \6%:Whho-lcۉj0,cŊY9O0(,l ) Ѧv5<˒umk3ֱ-Mm{[=ַmX %q*}nsVN7-weR]ml;X=j5@w5ooTwe}ޅok\B7*܃QgX (9awPp&51)`a [5.po8uo>.,6+N0#Or"+ky\ 0yd.<_x{C3HAHFͲ)c*ġL~{œPh+y WH) S4F>TDeH/gnt{i΄61JSV@h0ֲnE]>?ƈ Yd+{n hK{Ԯlk{ p{.ύt{nP;c++-annotations-12.5.0/html/containers/dellist.gif0000644000175000017500000000324314466730207020741 0ustar frankfrankGIF89ad!,dڋ޼H扦ʶ L ĢL*cfXJԪɈFA(lMvn|6Fe892g'Ɇ؉a():eəyʧw%I9JZx K֘KyZFz|-=M]m}{8,= [Y:]l̴NN n~oTf tBAc4x% qQFyhlQGh TXYHZ+մ#<}b!8SK+;SDPr97sG0MI#SRmZHV"[*l@za-ֵgsWOqN Ů^fx{ >8 (pW'Ŝ;{>͟KFYKvMe٘an՘ξ'im_'_銋#xiyɏ'B1ۿg$~vWyݤ|w|n`Sn)' 8!f5ŃE`,ԇԁF"H$H(!J4gcB;3[7.E-ҶUAdQFj$ 3H%S_iZZ]alFzf^xϩsrNDߟY%z≦xJY |rJZy(RȑfJi)X2zfV(JκVk~ꞦZ觔J,w:,vzP>[jNlRKڂm[Ƶz*D[z{+*K.Rl.Eo{K/&*x pʪfƨv\1_&2$hX#b%}+zÉRb8+@2)c#]E4QtÂJEJ,\7IN,J V MɿX / ` s,1d*sl3 hJ,ww7rDBՉS=,Qpa*6OM4=ASt,0Ç/ATdCO[tt"7@ȥ!딅'Qɍ$>/BJ4JYRc~,S)F@A)iL'F^C"&~O ըJuTUլju\W ְudA;c++-annotations-12.5.0/html/pointermembers/0000755000175000017500000000000014466730207017476 5ustar frankfrankc++-annotations-12.5.0/html/pointermembers/personfig.gif0000644000175000017500000000314114466730207022160 0ustar frankfrankGIF89aT!,Tڋ޼H扦ʶ Ls ĢL*̟ JT)=q\ zT7{ĵH3PhHph#@iai))y yFfJ6zX깪նP * *pKQ\{lG} ,mKWD nP-qn.*u_-ʛ0~w:iB/!fI`GopbQd ,eDM9#̔!#RK1e^O3I:4gĜ_teGT+S95+4ϯ`O%+*Y.,˶(TqY[7V׫yӚW][k?α^;Rf/ipe*\OGk͔E7ϪU8 ;GٴiwHkn7'ڕz̗e籯'HZ``|t{_swj"-X`~Uuy}qtagX*r%"@̉zഁngnDǢd ?ܰhBZdK>OvDDSBJW]jZ} fUff=iffm~曧StyHvI%gcAJbPr9*9i FzTjfզVj%v483Gx䪫k,l!4,1rʩbfj3, Z]׷fKnaje[n`鮺8%,ὔVmfлP{/'\3OR8Llb *)gbh!^/Lr ?c/#yLBϫRRg[+Vw۔X{FώQl[&wY,co{zMڂ8זag\yR=7yՕyڟzc5U:^*-~4ZI[ZcgwDزϻ]<׼s{ǷhA2)^ RϽ.g}# t 2J}觩zj*_ƿi^&yNC\Pvd( R0< 'yf$ 9/ǁq*X¬u3Cp<O$bK.KT"D'T,jXD(N1dlbx1qhd8qt kx7!>͈h/PSd?DFң?F d JP2$ =yGPђdI..`bYJWeoF\R̥/w^s,fHcRdf-KhS(eHB0@e9 SlD1IDTg:yFR^<'Nt6Sg49MVӝ$h? OTg>N38G(:ӄ`y Q  (/4^vԤGB@  s.|@l*%۠n1s JFDƙ)`E. 8H0xIf4-D0H.W*;'޹M*)NvSi%*Xfv$?Q'K!GGV3iFy,Ƶ,Y'hI @;DiXLt>nQSFLϥ`mBw+LjhgZ4>ըIPwM]Y_GA]iQC 4S CK"Ѯ^Q\.u$pk:Z_49!uzm_/Bv-i,־ݰPs[6!-nUcq:w-1SY&3ly۸Z7LM1{Ao=n#^}Wq2+n^jϼ|.yk|q_<ێG5pѓ6uO۟W9hzg_hux%Q 4 8,p"ׁ ,7z'"@~*,~sMq#74X6x|x׃z:Q[WP7P7"SkxIQKZMAWoGULWgAs_5f:PhRH!`?p4lhy{ȇ(凼v(nxkhhX{~,rU8(|bS8XSJXz7WO8mȊVC?muXxp؅ M8lhXQ8wZ0%8{V(vh$Gޘ̸zXx(8g7' ǐWͨmy 'BґiHБ`gtȒ7 D|i4x69[fІb9$256A!9i=l#١UVO4QS)3MHꢕБ P>#?>>H&?T?/UYq@CF@|@ Jaa9!UgI5jy):dSTE 5YEOE*%FddFFkmFq4G%eGrGG鑘07;c;K;;cCpYlY%]tC^SM"N@cCeTQ TQsH)Gqu Eȕd2\%5eI ^ 'rdW~L3_}X1X_cm8LX!Օ&L&`*`tae4ava>Zx:Ţۊ;e[uTܺ_YՕC6E&dKFE eĺiy%]^4^u^^y2%C5_5;Jبj•gJfgv泤)[b1bjfTcB[,^cD)T7vZħЈyf]f`&fAfFSe&":<vHJˊs+ ukuwkf{`}bdˍ{k}tˆ tK :ꎗyKsKk+K+;"ԸK[`+ފ{oɫKkK+{{p++x닙{+{w{+ v k߻i᫻'9X{67X;ly٫̠r\%q')<+ܒ-q/\1,yk Ç{.á+tLر5y$QV|XmdMA<9*>h|\|2I)+ np%pI)؂xyp~,ۍ~<Ȁ|XȹлȐ|̎쀒 wɚs,| Xd p<+ahIAԫX̯@+SͦlBAl,s,,63,p, <Aʼ["0(,)@)ρB= \}}3Bm"A$(Hзq%ph*)g|^$KnM#0M▱ ԷA~9=~7Nx;=~@.BGI K>fa$#:1+=ߜGmG`MAh>6L:.m>~%I@Ep^ ga!^ъ1bƮ^N™^^ =>a֞aNnZ!fެϞ1a!,..jn^욃4n)&-$̢? ?R3oڏA^]M%-\q]ٮV=,0Bu)13_Wr<o _F@AC)A3Aޜ.!OqߜKN-B -upO%c/Q!n}M}'QO#$1ͥ- ⫿ݥE0]~=i\l O|nǟϏ׏Oۏٯ?oO909+6b6A\"@ET. NUin]eUmm{_}IOp1K2RrRsT235upT6U6w6xؘjXyYW:Z3y:;j[|:<]v=^~^Q`@A4'A 000111222333555888;;;<<<===???:BNAAABBBFFFKKKLLLMMMNNNFO]GP^PPPRRRSSSVVVYYYZZZ\\\]]]___MWgR\m]j|bbbdddeeeiiikkkmmmrrrtttzzz{{{iwo~p~uʘˣٯ!! ICCRGBG1012 mntrRGB XYZ acspAPPL, desc|cprtx(wtptbkptrXYZgXYZbXYZrTRC gTRC bTRC desc"Artifex Software sRGB ICC Profile"Artifex Software sRGB ICC ProfiletextCopyright Artifex Software 2011XYZ QXYZ XYZ o8XYZ bXYZ $curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km, '! H*\ȰÇ#JHŋ ȱǏ CIɓ(S\0cʜI͛8s"ϟ@ JѣH*]ʴӠDtJJիX'|ʵׯ`Ê5ٳhӪ]Kpطpʝk,ۻxݫ-ݿ FjÈ;p +L坐3kTϠC_@3ӨS?,0I.X"Q4nIYNxF!{FX@LG'k׋Oyz6-nү=_"x\q`WT߂xB޵T#nhgsƇxh#p!ԈT!QXcO-<H'hD$J4f`FD:#4X_?R9HA\{[ǡO6H"fwFA"H8Tn'Pİ <#TP!hB,Zꪥe1Đ#F[ҺE%z[nON o|9+BvZ4e7KYd6[[pF?CB%ʈ6c+A.p&$GslYܾOJ "6,bd#*F̺tzlU6R(~=PѭfR&!{́a z(BcSC?͡T0kL\cz3Qs12\! >*6fAD#8w6ܸ%797dܓ~Gs֚^*XeŰLZ[8՟"TgS gp5kOJVgx-ꘐӤk*: וp!3-\h >&vXJa 2&+2 dz?6]bC5z}RՓ^iNe 'W" ҽ MVɔ!.'<5FհgMZָεw$zdhLqraj'0p8|v R$bZn{w}]=AhCqh1ubm`{V5A-~&7n"oLcr8'N[ |Y8E S|fuW_\ƥh;+a@.+yηȉHO:_똻zHLUX'~<~+`5aCR9G{zE}춆)v9r+Ww{g9kw:\)LvϼOƣk)uO9?kKq7߭Ͻw{D?@̮|BOn#Ͼet?ïmo=x4(uO7ǹ7@WWq`({ j(sG%.׀jt؁gⷁ`~xVd!(z}(4w,(2)+XzdȃF؃@y$hGFKMVP>8|x`H^Yw}#ŁaN4dX}UpH1l؆GxAsHAkՁ7Xxi{ȇLk'vPx؉_`pXՁ^P8Xx؋h6}kw(ʸ،؋x8DRxؘڸ؍A긎؎˜1{x?Cf9ȏ>h^I ِh W y8 !S 1h"I႒I>*ɒ4.I@1i3Y<7A9 RJHvv?yXVyXZ\ٕ[9??p(Q7p(7_Jɐw  ;h7aJP?Ўdy^p)(ȗh8mIؘx j^# ahJm _`J0(P9mp^mR wp#pmYI? 9ipwy^p@~ q0MH#Н7)qYYv 8 RpxY٘_`)9  QR0`Дɡ ٢0ږ ٖ_0%zjp ڡ!#mwY7^ 0X.]@@B;D[F{HIʰxjTkW:Z)Ęz$8Oۓ+ocKf}}P2*nbpWgɒ}+g 'H_[!kw͘rV۸s*w`u|{=v;+5Id{w[:/ t iЋȋDH׼qcb۱Pqثxë CZ!rKݛN94;A7Wː뷇 (F;l Lq% }gkj"\1x(̉k,™XǿWPlk(=< A C^9D1\.km2ڑJ||[Gꬑ''UyW\E\m>4 A_ n+w}w*d imkPDpsļFĶylV({ku !yw<\ȹF Ȏlqa;AɕL~} ˑɳɤlQʦkīʯ쀗pm>p&ɶ|̯g||˱mܑ܁i<\,͕6iY̴,z/L|Ϊ\7jh\~7C5 [<}<<7W8EnK}jQLq<*HEԤzCPwh0qZ-.HEե1Zf`-ovnMŔ@SJEEgSGu}'FMI=nLT4p@vT-o<ًqΣ,tEqGerNˢئ=uq֨]t=ImӨе|P*+@|BDtR m' ݒ-U-1}^]SޔM61߉,im߯b ?\5i. n;hǫlAm=V5խ&:-WE}*ܧ  *nR0NhH׎Z->s3O><ݾw츭W0-ln>ߧ>n?'.~~s8;n L6^V<]JX֋^.mA/Wo <(>De">f' ^r~1\?JC}T,7bQ(@h|c>fr=>bAoX|>/ć(jt>@?a(ښt~[^/ˢLޟ>,`?_ȑˣ2~&-.@'lsӐ > j{O+'چ}jYDqf   $ DPB @Æ)^Ę"Í vB%MDRJ-MN`L5m RN=5JSЊEbЃG>%ySԔvPŚueΧ]ZȡCXe͖( =ruG\9ޭKݼ{E!r޸sаV~%|侎n"]og@a`g|ldǫ]@TgJ*WR9\pŋ:ǀȍ;7]tsrBP"k`]xѷP1g-~"рKA[~w7 ;c9dp:D:CA /.6D1E[@320E0mdp /  xDRJ>РHK2^2KbKjD @ҾC>C 240rP4$ACV2PAKCz<C1>mPN>,,@J(O R4UUU*PW J@0U: )Zw=nKOu<@WI/~@ֶV_=4bMG4׆vZTkSqBfzZ/GsWKjZ ̵ͪXPw^}<ӣ4T[okJB"7Kلmjaň3ҵ2eh2erc:&KRC )c%m)&( %L9(׎hdVUe{Vbbސ%[Q⹐/. %{B&rP7`DC [R7Ӯe&Zj}̦ETk߿ 濒P{&]!fBL OL e8õς [F(wC/!v3 g% f;(/n q #xhЋ_ q<( xk?ܠy  g&;s^" HB |RHF0hX"m4DKy+YXi6Det|\Fb/3Y&⃡ʒIa0hʛ5384f6,'.'gLol&1qS! 8#>zANiMlSk'i;dϟ-t#/Bat%=iJWҗtK|hE9njR4fԧFIj-.Y=kZךk3[drֿv_{ɛlG-z'H@vmnwwŽ]_ѽnv(~r=F[KwLg߈ CD/+ O\gpC<wAqRq}+Q"B}OxOODg:8tFYr}|vqtG])zn{dz:]ϝw|9W{G9_.xF;c++-annotations-12.5.0/html/threading/time.gif0000644000175000017500000003555614466730207020053 0ustar frankfrankGIF89a             $% "$&''(("-003""*+ 0033 , "#%0&""&&++ &"(#); %??-).6$?3-?6*08,1:.3=/5>-??1>85>>D(6C%D%N+B+U.@0V0^4?D8f8l;DDUU@@ffww6=G8?JDDUU;BM:BNwAffww@IVBJWFO]nnNll\JS`MVeP[kQ\kR\m\le]bkW`rWctZfx\h{^i|]j|cfkckkkkkHJKMQSUXX]^_foxerfriwo|n}uȡׯ!,`H*\ȰÇ#JM ŋ3jȱǏ C iqɓ(SLɲ˗0cdr͛&kɳϟ@+J΢H*]:(ӧ/BJՉRjݘuׯ`v5`lتfϪ]6gŲp8״vP`Yu{/È-obK``ʕ1kެU5-6vl`MVM.Ϯ%:!ءY̻7SϬG|1cݸN}pƗ~K\:u껻e4M>Yˣ?>}#cxh{ui ya7 ngWڀBHBa2'" m"GAr7XclH|UgًDa'&HcF9:d]VzPFf_Kw#V>%Q9IlJd 1f}*蠄Nq)<% B V0t駠fvN$rqVY@"RjgqꮻZFrh\yus)\s%&^thm+w~1xbɟ#֭.ʻ$"̮v.:0i,wgmT&"]bL2!k1lL0+2*L67\4M>wΝ}t5O bȾPMgnZfb;H2]eIvܙ1 L22p܂B1"Oa'+2Hdvbq>+l:{Lz~S/<+0[{1Pzjc-kJZ l]u[J f1eV(Hj[vYʩ3VGrs U0Ghv+5Lp9bB*126N-HN8 ` x'PQ U0[z!r~'&a3|Rr׮ -YbG[=^yc= rhxXϺַ{`{ו!H{!@?Nxϻw_=dn >UJՋDXe񐏼w`삯m\!H&hnQӑɛ{^t̻^jPZ+/}w{ȯ=A{C#_$}?jT}/ߥssEQT>ϯ(w 'wҗ~հ~~sG'#b&wsvGW ( @ wn 0 ( pW 'Aa"g"+L7uၽr $X Fh~ (nx--qt\Ԃte,f'@ׄpՀsׄ tWfh8gh{MX 70 !X 8T8wxhRm8Eyч0w7 o~Ԁ0 vX~(ogDwT7tddհ (n TS֊ *wsk8F8 ЀgG8XKʸ{(wPt{ysxHwx|E$$kb#gwt9Yyy o PqD &y(*,ْ.0ҀEyH7A7t.5xO<r>HEٔsH9%$#V "Z\ٕ^`] fy` 渖l9AVoX).b yxY yٗP hYyَoM9"!xwؙI/pi {G/8 vx9xY9tY*{|8LQwPwGvٝ9Y 4/{z̹ɏ yXXuwqDjP :Zz vYIמw~9JQxʟv Z&z(H (~P0 H(`~ Ԡ @ FJ$IWj L~7pnX 7x` "ZA):PJ Ġ%Ԣyڄ8 @ ʄ* Xm')yRTZ~x L( H o#X'+؂/3qjBsꧯpp~Jw:..*yp!Lh`_HsG:9yZ:}Z rZw zIHpQZ~$~ʧv j, y8w*wʡ9 jzڭ I걷mʆ rzJʯ0& I*y ۬ج::늂ڳTx L{ZHC) t0Pw@@H H@ Hq[ im6+ X rԪʂ(JDGH I˹rw(w؍J-۵~ J3[ 0t@ P t [›+}ۻz:z8 `n ~,8 AK0 IJKpFWʋ ; ЂmZ>^[z; tP;0+ H0H@u* (y茝uµ+4L"|8yJ{ty+*\{ ȍ"lR\ƻ9, \A\%Cblwț/wTL ͫ > [ ~@yLw 1)zvǪѹYw TywIw Mwo2,}m]wpLuG dƨ% '~wݪҼ,><>@B=D]F-iP}: l8 w(8zS=w8 t)w1s PWw إϠ^ʤN1jPvW;h=wrMwl Mqxg*SMu (&t]vͥ[ZaO<"w`u%(2} } { S PNXȄzzʳ׃H۳=wj۸w"H&׻-(۱zE{Jܧު ʍ΍ FY֮MwHJ8ڋmՠk˪*(͉n zgJRXww(x ڮa]i)ڿasXug/sGn; $;kWk~IB΍Ҵ-*}@޸(}k؆Aj<Ρ%~-. M gL޸hNF(njoxcά(ͪ3h=8}{y.wV }?Zn揜ήYkNr~[ap+xmޫΉ'ތܔ{gݞ*n~߶޸X샘Ξ.xx'%+N &q~F d݋(rW {׿ؾ(ի+nn">?A y" njK{/߿ی1Nu^qCvn.w0*Էʟ _wE?[wژ,K6*ҕPYLωd{yj ~?_J--y*-,8؎,M耇绷C_ jPmlz?_?|l~ 0I)؟ڿ? o?h PN?P/pB DPB BQDQ#Y<~%H%MD2-=ҘL5m@N=}ΡEET)ХMbԘcIA\^jǬ&afTlNc hٳmݾ}܉PN-i[]ǯ=+qܴk?bfnyG^M`=zwwbr߁?|o~6G_zbH:\={׶h?w 1';>"v@+h'?Я~|? VP|D=(@̉UaP2t_"?W A`wPD +)(V 3 5VъsadG(" ?p=:@A Ke QvuK<ʬH84#3őv(GT.+fD' HN",cwI:R\;Ώ6|ENo& ;Spg1t)RnGg5hv!֩ 4S^;?T 1z0@"~3%lV>ݤQD!عgdԥ5H7;'E)FRqL?Qԡ6UEIRzNfLuPS ZU^}*7Vur[}LWխo[)WMumK[Wƕs_6El632ֱ=c+YBqf5{n6ڗgE Ž,D i=YRh-:[Їlq;ַ;o?6S5no\ ent'Z`Mnvmۨ*>Wjk >r{\3 ě^&Y%P%-Y0B<`X@З.tG55`-ow\ꄿ Ն򅬖Xv_pd!,PBVtCޱ%Fqk_o-aBOnш3)'Yυ=Xgy3M8DQ% (68;cΧ+yJezD\b0{T wS"f.vnvw=ozm\F[F_3 bN&M NA5$>qWx5qwm-֝aJ \|p(LIΎnAs?"6GGzҕt7Js2Dv"^A|qutgs[OͦykNVs,b|pǎvW;ia ߙЅ:9Yhqps~xҗ2nzr4i؋;x;G}uz+ܲ<٩Agovyc߅_ fx0~wם};x7T@1>|ڇ?Ϲ݃_-_ 7dՏĽ/0+bT8ڂћ8@Dp2 J2p\#D]Jp̾h#@isAi@i8?f?f0?TAcAk87)4AA@p?$Ծ%l'tB3|jD2B1TD4É;;4-822P?>=2@d?D$djCC:gB;AۅBDӳDMKıAGLC{$H@ tCDJ@x?f@4?D{t=lʪ|J @ KJ3870Aj`iKRD=8?5;j6D;LTDT 5ReTyQPɲ[QgPӓՌjزԲ{N=^-=`Uųkc=1(9sWmFkUQx\(ۢriMp]$Z'ZUKb#eI,JDpJxR,?DS@D{Iy5zWc#\]VVP%E-WF=qTJp_ 嵸蛸՜ͫj`diWLLD4쿫Mfݫ$ՠn*;)6ʮ6;nGc 4k NLD E,l8,dCuK8ώjV>XWkϺGj;C$Y.^j;<,k H4Q̄ 1mEmjնG[K I$Q'f4tLTHD'EFGӫs;2Kt“?t>DQWRSGTdVGL@\]^=0`a'b7cGdWv3P%pgvg7Zg1jG Hlmnopl'Lo;k 0uG 0EPwvp:Wxy w|a} ~ u$?،3g xuj7xX?`xp萎 ! ɍ('7Gzggz1a/Q  izE r1B޷{ : ܙSw7 Yqtqw"*,!?Yg!{{N4w/ ^QY8% `{N|{L[E1S 5|t|^?| Vi`П|gs`cF}}SR5hvpaPpIY(7 ww~|[=J&sU/j „ )!1b'Rѡ+W7rx!Ue!ʔ*Wl%̘2gҬS$,~l"ǖ,~T-X$ WS>{tT\EthѣZs*-JBČ@x/޾s lH1Q+nܑqW=(Jd.̚7sТqݺ5z@W^3lr :S%d< Q%DznTvQ6']0!, ?L $ByS|} +t$rD𝗞)wP  J!hY-r!6alUÌ#VRwUC Wqǡ"'oLSM'%Rs@WtWC}P EM:$|@Id%FVe &q&TauR-vՇrf&3(Xd5`ָh5ÑX y(^VII"dNҠCHRXc*Ŵ)=ǗD>t+\t+kM"*)Ahv:ZX]4N3z-6=df"JDfCG+ǤhVdC/"k d슈,9'6:У=6\-zj.{e.i01 5Z̲06Zco K'ϋF;%NwFd%q]f޼Ug]9=fK(p7y7}7],أm;:܎e0-4@'N ."{_h5xYt_Iq_*= t" )Ř{~+Ą9Q"Ow[="|1{=a1PeHeٻ>Ǵ}0>ç*ɯ< wFRfƠ_y,xQ u@.#AiplҰ6KC>bfx!.dDx"()RV"h#r^T!(1f4Ψ5n|#%ɱv#7C<~)A{,$"r|$$ HR$/Mr&$(C)֍'OU"2|%,XҲ_-srz aSn+&2iLp)䗦)i)Լ mr,.|uv@Ҷ"]Lb\2.gE>y"pH8BO{2t| *Ҫ}oG;JF3φ}Q&Q|XhF5qi$`BKSԅ*m%s29eӝ25~OWpCJ2mrϙp H`P"?!DUdM+VXJPzU3seکDA $Òu*-)sdƬxl^)Jl{JO=DT)+#Bln3ov-pe?QN"VOSVmçJն'{WZ*Ʒ.xfq͕td`CZ񼱝M^Anjֳp&y$F}Ie5XBd W"IzĀl![:l_:F" ╌K*^aw0܃&ɮ=kzZ5:VhUb,_$ww<:$N1sY!'e'Ͽor0|HSZ a#6Ykn3Lg!)TS9Ў^cRbϐR6ў`a2ilTK7-Jdծ~5c-YӺֶu`ez \N_/ժe3~6-iSmkTZ&^}qm)mrg&8/QM<':ө]M}KDBh(f.,rqv&#B(G;\dԄ~ M@ .j.i&wrpR]Dhi$K «>;rQ[O 56#4,59(5{pAǣQobgw hhE3٩176o}S&ܠ89.7^xt#]o8q*5Rg-S^$3!dn߯hMo|;cо=s z̟/_(T _^ |7 @bB@ZtZ?/f;}u'Fъ@<OV}DLT*I,F^]Q HFEARq)]*OTƁGUVVeTU~GT͇e [[db|t0`Et_tXnbI mIĊ eY֗X٘IK Α gPhָ8ii!GTVVIXn~JnJ1cV"@!0I!eW}!v8OX f zv zRʡf@G$z)^l "ʼ wH29"šbV؁a(XnDqC~CD  EOFz.$JJ$KdBtH$F2/mF~L$O"` &NdJdOdIDN-% %JETN%UVed."9)%RVre)yU %ZZ%Zn@YBX1VQO bm\R]!ᥣ=+h@xAd_"]& Mg1CAxDDf Qf(Y&+f:`cCD_.>>ibffՁGkf eR* q-Ds: Q#EPLBCo&pp&)Msx2ify'.i(UYq%U z{!hV:Dw~Ѕo:gqd>肦gJcMX ^FlUVIf"gˁ"&愊)o*' z9ɆFB}yD!a\h(sY#]yhhhV}6^}9dv i%h%&`ez6Ji(V*ʊjb- pb rnx){JfsFKrkbqT5V :#UۜhR1),*8*y(HmN;>"ϨX?bwi:),jt"mgEoj>R&jj^BgNE)+zf ܔcPQj*.wbҕy&RJk6+kҺF+kkҼFl1hNŒ*R.l11133355566626:15<888===06@3:D4;F8?J:BNELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km,uuüϨDŽŭߩՍðƾֈ *\xqSǰŋ9 &4j2I,I(ɗ0c%m͛8sɳeiJ詠F*] )SY.JYo`5N ֯~]N,h^ o7xs+ FT"hBX9H㉓4IY rHX2^!( ʬܚ09nѐ06p9>cܟ$9s`f&C>3!=rPuS>}Q02\';32Pl&>ѹU "FJQ6͠DЋ44wT28ndfTyOrԥ2|@B-jPUUCQԣ"UF]S*բFTSԭ:uVŝdSmEGȥ J~_C,rSaN)ą1 ! 3Qj " x+F X\FqXhR@ 5d1y+GF2h` TPex)B2G 2IZРMﱹn.D>gLF;R8n3@C_)DycecĖIMlٴC}+SqקYMd2LRɎ{T-PZ9Vih biVdžvq݋~rFMR1EO^wtTyMnw[JN!]uv^c^Űp'f͸7qհߣ"QƲQ(KRnG0aTsIG9z\DV'N_2CdGlDK#MНY#u>=SF;P@ 37S~ƚmרtlX}BgqHT"ݬ Ixx7?4$ }0Mfqw@ J]Zjʹտ:V _&O0eʜZ%%c|]_>{ͣGAtou썏4Я+;@\mwk#W~L& e ݧvgg 'kV0chz8ǀW(`a|rNjy!#g!?rVx8+Xtߦ1`󷃭g, u.KG(C.X R4?NȃU0WxWRJXlօzY {acch f(Ӆ\dxx|ag (|Q~p؀?Gܷ~vXsDdw]v݆xlxupd38v~(=f\wyXzx}Ȋ>ч }Ftq7z(wL{hш[i#aWq&4 eߘixZNpYyșʹiМ9ԩIؓnjxhН9YyaMIIXٙoEޅ"X@qP8]9X{E1{jȟѵF"`P`5׋&;v]OKul7&(! ]K P̓iY3: 9=(A:_`0P߅⸡ѠSPV:TpZ\*Tʥ`^djZ- %Uep TqZP sPU:usڧ\J& 0N'yC,s:Zz:i *@r:ZJx<`ڪeI6ʄ8*zr01 ګZsƺfXuʪRЩ0ZF: SddZZ`dPگm <f[[k[;:;$+{ [;%;'1;)ˬ^B0E(r N DN*!+MPPa@ƺвO[G+[KT9KBM_@c- s zLKl{{F>۪ 3й+]FËXZKqGKK4DJdVk þZ뺵{`7[XFVkNtS75FLdMKL#Hc*ڴ꾅FSZDF`iDFa¡QI5P`9<|&>=@L| ӳƢĄ+YZpExQY]lOi a,5FԺ Ɩ୑ļJǃ`,n5WX̟Z\:R4[R9Ssp,=r,B\D :,Þ;%WUtoLGop[W``EuW[9ܶJɕ`E|`Ǽ;i` p ЋH)uSlåuZ͐lL ˒lŜ}F\Mkm OVvؗhqh39SMc܊yܱ|S=έ53^~ >^~ h$(=p$nZ}{|'㇁1{ )9yxwk)<>#a7:(]䋘6ݨN~#~(ixzLT=nS'8;c++-annotations-12.5.0/html/polymorphism/0000755000175000017500000000000014466730207017205 5ustar frankfrankc++-annotations-12.5.0/html/polymorphism/multivtable.gif0000644000175000017500000001640314466730207022230 0ustar frankfrankGIF89a O  !!!"""$$$%%%&&&'''(((***+++---...000333555666777999:::<<<===???AAACCCDDDKKKNNNPPPUUUZZZ]]]fffjjjkkkooowwwxxx~~~!P, P)2+!#"#±ц")%=@HJMON&0@D* :ߌy>}Gŋ 0n8)Hɓ DQ )܌|sLaj0c*]ʔitիr`t"hf1U ֳhiMʝ)C&L˷Iu@f!]x\%K% ¤(!).> uc'H8KڵoMp4m Fx&w9eسoҌ8&ӽ?n>`@\@GqKI5 <:%5P%#@~O41r|1A *@!VgC'$8hQbA8g`V!d9F@P؂D (2.fL^#S6*^@8M~<1B cթiďYx5Ԑ,ĎmYrCP{D*vP})Np#'v7^gIj~(n%@i̽8rIQ[NH] kU#tDJub~eǡF+վeګjӁk|hP69m /9˧ H ~$Q51"O8DURY-*za7b'138_\3K>I_[]D:ی9tḘ̇3 =4|eȍSC=g W?`D\y/.Dw"/-9S+7xHx]0Z!Mrj4{NhoD; ɗ8͛=GXY0@'p~@`$D`NU,xEj pt0 c d`g,4'2Aec H!y Vt 9Ț0sV9D,'k#.!p6,@@~>qyE1O0C qẍf@E2=G+s hމd_5$-H I>A\`*O#@%Ȥ,lj `@p &f6%,@$wZ"$QWQBfD1s)  @lґ'7񙠬7((J.h>@v脤y7brreAKgɋO m⊦6uKE8d0'*XN  @aXMZֶp\J׺xͫ^׾^F `KMN:dc eЕeeflVͬ,?.p5hڷ6ukWضu-[qKvo*mi-.&US̽s-]NEKK .Uw ^I7 ovX6½LzqYm~+b/kߥx~]\De¾0%Wa 3eKp"@|\{&֗bħ]e cس7qvs㺮Xy~l!g@DB,YONr%&Ų#e]ry0bfˮ9#&3l g˼2hĝ: M4}6s~ ZIJ3cgE/3-O zx.%6Nn_MVcDӳ4l}\ZME|f`_8דv]cf׃؏6vm^jKjkCٻ hWۤvnC{nw߭x{fQ۳.;<oa{p.meV\Wf|lȩqܯ'nɉrܼ+O:oǼ5k|s|^=]EGzA{8n:uRW~ekV׿~5{jǾhOwwߎ ۵l>پ{O?YAH b1RbȽs߃@P-z33׀j &U@eŷ?=b,1 mXi%:I@$+9-.@!/ݢ-jTaX'B1@.$D@S/:ЉUϖ_"@8X2t脤5a1nD875df2islӍf ) Lh2C88F7=SS;cӏ Uek%I#@㐗1#@C<3<`(<tiL)k] G8>30;֘g[yF`ГLf^[/7Ox!&U6\B PVaKwDZdյO`.H`9EAַ5neU 4|:[O*Nڤ6gTvNƤZZpmMX1Zv[l*zl:uYVzvt*muRmoqZ&>c_:bEZCY |iFWz`zک `_::j:Zxtqjazi^a)yګxyZz9[i u{ʝE@瓜@ Pjx D +;0J8BTb*fs `@+0>PEKаIJ Zg@@ &{( E4 t @$C)@G8` ЌvVg @;PA[VJ+p"gh:i4 +WjJ`gƴ{ʭ;;k۷~G./egt wN+9 P4Aq;mlv)9PtzŨtJ40;[֬awws7|K EpGdZvwj[;  { Ƽ禧˻Eb JpnDBKC۷E`1lpڻv{>A~- ,tlڡ{+@{E ˾bpNfipzG{4@+`I@yK$J;9|{Kp;: Dܰ4p >'LE0VQq'{ {  I `z,kQ<|;rlEPaLJ@f g:k([ Ŏ_4+oª<*[K0&ʴ˾0J|ɖ"L ǣJ0 {ZN&nUnW;[-? WKe@HL kU]Mu^ڜ+` @V`^n">㈞b(;Xg~ cWqA:æ ّ jK簮~ oKnk\]փ^`>!AZm>a<~7L޻Aׇn\Mbk ).l^YʊnM ?$۴/ ]0OB~Z8c/__/}+Ho類аR޷68ö˲> BYlH P,hݰVEAŇ?<]>xn,tlxɞwJ0LJ,찋MHMP_fo l\,4R48Xsx(y$yə*:J ZJz + ZZ;ۋ `ٹ2D"sX$(ixT PxyQlξ#1k*/\o|Koo߿XʵTt) J!mfKXLI#.@2ɐ,[rK4kʜi ͝<i6ܖAA@rHF+)h@OilkZ -05l;Iܹ|K7o?4KT `w/%!6ČzK496NƊ>z\!g~M 'gشsMsA%0:pIpו\;y,ƕ;&1;Z=ܻ{8;tvnnv;R(?`Aa`r܂ x ^ana~b"؎r5"z4D6ވc:jH";p-*ɽHuRN> e=0Bl0bY-E_QIfNi ffH>o4ifzވ&'re)dsfgg(!'+ hbFtJhIu¤Zj+Kf¨I*&V:ϖemDcL. eDdA=+Wv骰4(&2 bByz-SGzɷ ^ p&plpqP֢ qlI"ni|Sz [!5tDDkbqˑz$|7d{ tڌ(%8 0C)y%pIo}! ٹP-d_jukI48Mʓtv-hz!@5t+@t۝1y+$-/XHxzk?45Nz馟zꪯz뮿Nb 8yczm-JI1|O||?'њRYI@:m}&>K*\ZOuJW=]M¸OT !l,*p*ƿ+ jpr4`},!'Ps]~һ d@&,a0^A(̪ JͅJ @3"P!kC,Rk@ ($a 0A1]XK A*׸;q.!Dؖ1eerȌqj! 71G `K$,>f1$):n\B|P'ŔU-5ր:.`4!JvPA{EhiLX`PHw-%KL!3j`lI0`曶3w`dZV," G:w `NЄ2p,$ {j%C/@;c++-annotations-12.5.0/html/polymorphism/virtbase.gif0000644000175000017500000000236614466730207021522 0ustar frankfrankGIF89af """&&&''')))+++---333<<߭_$|xP  \tۦRb[] N+;9 ײyW`Bؽe Jx-C$ P„ L}dkU-vW|ceF,ͻoT"mvgvT Or !t꿵n߿+p ȟO׋97uHpr]m'X?7`AX`yXC wjz-Q&.^"H$w 8~%@(d!/>ȊA&eT:ieRѤE2Xc2gMZ!]%K֩pydu2Ddr'tVjD"ٍ2֙E:&o^iۜ褶T*fi(v)6Nꧪ ꞷk'+馱 Nb#"X*Bk>;GʫfKmȢ.26 &cȱjߊǗ2j: X|rHwg{kP\1h*sl!'{#82g3-K;/rLPLut-9~ bvIKx*ۙ mww-|l4|K7zs6 ʤ%r̖8! _>u㓿Cʡwm8:l`')w/|A;c++-annotations-12.5.0/html/polymorphism/implementation.gif0000644000175000017500000000524714466730207022731 0ustar frankfrankGIF89a """%%%&&&***333<<<@@@CCCMMMZZZ^^^fffsss!, 'dihlp,tmx|pH,Ȥrl:g/*ZID5J)iw,ԘՖ]{eYX6c YTQss]Il_c{l T"Y^" ]"sq#T#U#  Lv֗h" zWqvakhik^a?e]@ni@4x0[ ]X!E8 ۣ _yɊ_*fYK'pD FTL 5$,deHR `&S[a*ӧMGbmԩWq A ӠAPAb$Vƀw!Զ8rkb uؼٰ#z)RJ34,0٠)36`WJelnc}[ .N7r0ՕY9ϫ_{#{OϿ(hgǂ 6F(Vhfv!($h(,0(4(c8<@)DiH&L6PF)TViXf\v`)dihlp)tix| @i")":&:h)vਢ.ڔ JZ( X ꨤjꩨjAVMd i;ꭸʪʄ@rڪk쨻j*˺l*hfkLjv.B*m(ljkv{授z+nK+Z0D={/+p{r00;1[o\, ,t=s<\1<*ݯ8RuHZBQҖ5&ԬF>˜7j˰@7=Ѝ>tŸJp. G"7ɍ>pb}GkH;$ȆH#BPE997ާ/ lQ,PJBIy1(4k | Gx@kŔSo/[ܫz -3YLdv'ɍk?ٍrp27+_v X̠7N, w1JH W0tB(B3f&ܘGFC]Їbbh6шRgCrEjQ$U>΋e@!~_H&ZMRۢF1aX23>. 8EnbG9ղVà4t*6RFIRL*1̑\"UHqRMKɰZ j}$[bL2LWeVč͌`$Y6Zjdd)M:}|,Ǩ8ȵf pd=)rҜy#uɠję@HPF_G4,n[&·*HRG ɀzc iFΒLJ89,@UN8$NFdLQoȢ:PxBS*2Uu3꘴U$r5L_*R5v"YO֕ (\V.u𚥥QT"鵯&J 6Bl)a6,!`lg=F6NūiZPvm* DmKWH+Hߪ 0Kh{ڴJJeH h"dtukde+0@w$%h h։oh\, ;>owK :[W փOaAeXxm4VQb X+b^(mm 2Q@r+:_LL"3Ȇ]CRR."m+_t2e0#%s-f?'5˧AM?:wh枟lbBNtA3ک~tV%HSګ>3"?.B!A"+JԡFQ"&93Oot]fGYw>+|k:ޓiC?&ڟ?|vo+lEV^3kسx.orggQZ5Ss&gR)gm (uj%<";c++-annotations-12.5.0/html/polymorphism/internal.gif0000644000175000017500000000243614466730207021515 0ustar frankfrankGIF89af """&&&+++333<<<@@@DDDMMMUUUZZZ^^^fffooossswww!,f dihl0tmx|pH,#)l:l$ZX2zۯx,Oskw-Cv+={L~NJuT`;:=8A36S@g~þƎ(Ⱥ%?Ϫ HwI^1M3"\p&I#|/]'j.j\1afI^ɏ+cӠl0MΘYMGpTS6,Zȣr iOEE,jdۺ 4`AU{ ADh"V (A% P( ê Y& 5@`) PKmp-@  dPYBw[y P@ 5浥=dt A 5TP@{} ^/votdao |aiS@tEAw#A GF i=@PhvN#$h`b-́DUŗUMe%8Q?J%SOj#4U9!}38f˽eYhUn;rvyfy@l 4裐F*)) :馜v駝ԥp'^ x ŒlX+רl k|:"kG~rq+lkijFv/Ѫ)TE HnA˸b 4;Ȱ*#üI,kf/R\ﱄ  Xۄ>bƵ"LֿXpmd$ |J.4w+;k۳*;csv jʴ Ӯt NB"D_+eY'foh]ݶgj!owNM/Zm~!^Zw0u~F h"O+ 2埌Œz.6ζ݈L筻.ߋVbu/?r/x~<ѫ}%; wNpT0S#;G>'`+KKk/94ֿ\Owd` Z B;c++-annotations-12.5.0/html/polymorphism/ambiguity.gif0000644000175000017500000000267014466730207021673 0ustar frankfrankGIF89af """&&&+++000333<<<>>>@@@DDDMMMUUUZZZ^^^fffooossswww!!,f@pH,ȤRj:hsIZvzܰXȘznt~nkpr_t}zoq~djQxmf jii`{ uyxv m ff fՂN{ vu \@x `,]0 tT<!B _ [f%?Npi!P3PPVpA :4L" 4<=7GOW yܠ(X_)M 6FnfŅpᇗ(b#ax&~b,Zb(!/h8#T;XcBX$D2&ɤL^%{VYĉVfYZr%Q1*ID)&P&:j&efr)"wgmfh b?2񧗂™4:YTŢR6:)^I9iRɨZ饞!Z*&2jkx+jk [ i))~:r-RrmhزeŎkV芮%ֺ#kok,.o"nڹ.l"?j*rܰ#q^iƹ(l߯b2w'Yr! <ܧƦ*{sG!t; N[=sW)Oma3Lrjcvn o)v]wAw{mوu[NEUnL9IwKN疇<7:{:﹞yv T^,gRA 0@  AkXAg@D`0;ĀpAK9eO_/ٟ < 6CJ!CT#"hV"mƌ`U U4/izdْKgRΜ^E!dIGk:mTTԍTLUhVs"* 3رvMkiҩ+ٶew޼ -\0bK%.Gm&LY f3+NRgC6SϪz ;٩/оM*Cj3 _ cE~_5ݒύ3bj9=pM4gĶ2|UC|zeD]YEG ]Ju]L@2AIS=ǡνeZx졨֭!D=@ԉ@T߀8_Fc3X [R8lNδ!uXYfGb\%WY+2I1*W|^>>݄ˏ@⨐Z;Ҧg~6aPIt68hߐDfrkJp}I~ =h(ITJwre`p+W$*f뒤uGU.ˬH4 -CV lRbm{rk6* x&} W;o%njnAJ5U~j-osibi Xo ENK91-$qI"kn6̰>d |X˜ ./Wl.fҸ܁L,uTGu$?_صA[M[#_sk%/m,>usK=7ځ#^ۊ/9!AH.+X~?3xKk-{|lf ٫D;C1;d78ۧ}h'Jćz[dŢڋ_)|:E!BF@]aCԃRfdU3ZZ0)|_Q%kqa7*)i ;.Uӟ|0~# Xs!a h e+2 kE Q QD%^0,u!ꃭ[#TFꑉclA<vhE-ad H1^1\0$REґc< N}#:)BQBwTe6I"L풓\F3mVH^j,AL w$V+dPbDHUgaK#ȶԵsh(uKEiU5Tᴰ%-}W\=7ɭHcՅד9F/EٴlD> ]wЩn-ʈ N(37˨~L.X\@DG2#xBcUQCFV^9a..a!0H;=iڢFq9'Bks" 5C{A4b]n\^Eް̠Mq_CRdFd)tx} P۬ZSjj4DsІ4}ELU}tXmq6T賧PzԤ.OTzլn_ Xzִo\z׼ ` {.d+{n =;c++-annotations-12.5.0/html/classtemplates/0000755000175000017500000000000014466730207017467 5ustar frankfrankc++-annotations-12.5.0/html/classtemplates/notfn.gif0000644000175000017500000002443414466730207021311 0ustar frankfrankGIF89a    """%%)""-3.316 !!!###&&&'&'#(/+*+,,,---///%33/5>(88-??000434555777;;;=D=DLULUNWNW1DD:BN=UU>WW[f\fjwkwp}@@@AAAGGGFO]PPPRRR^^^R\mIff]j|Uww```jijpppuuuvvvyziwbgujnuz}ʣْ̔Οݯ!! ICCRGBG1012 mntrRGB XYZ acspAPPL, desc|cprtx(wtptbkptrXYZgXYZbXYZrTRC gTRC bTRC desc"Artifex Software sRGB ICC Profile"Artifex Software sRGB ICC ProfiletextCopyright Artifex Software 2011XYZ QXYZ XYZ o8XYZ bXYZ $curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km,IIHGGFʳ̻~; H*oÇ#JHbD,jȱǏ a Iɓ(Sk˗0cN)͛8scϟ@A Jѣ"]ʴSrJJJ5gԪXj%y8`ÊKٳhӪ5f۷rݻx˷߿{UF+^̸`ֈ˘>̹d3ۥDFѨn犡A|G %o[ b컷P7YF37؉g y.W;;5 ^f F=qA=wx!Ci%~ Ѓ7 zu{w|u1Q_^5rDG߅!3j 24m/vW.F)!^7N 1Dv)v !y%`L$-d]7ܕϭ ^ֹܛ~bhi]U\urENCz*FɦeL' P}7q`]6ѣ27%u@ ߏszm<`A]1aJBzfVkz-Z]Pܖ(*$nBjkкɫ/C`~d/z{п+0 cA' WlE,ZI 1Aoegqjf43V3׬7W@/4rN?m=SUL'TK7-u>CXSMWg;[dTcv9aהpӶLoǽ1mwxC`Qބ}vSE&Q8} ŏ7J}`D&d*>n7)j7( |7(KL_'G!Wog}PL[Gw }觯g?~^?)?˟}P0^ =`P2D kư~PV@Yɠ@9aA wP}8G= e\MdX~իlˀ0LXܠW&jzU n- $ Z8JpG,  HL"F:l$*T5X@_P NX .Mӳd*oO! +%1IS~JADIJ! j2@ҳcjZf"-Gnz{,X s7(\wE顳 WO݀U% "_G8$G&< hz h:D|abJzOq'UOJN`\:Q] % IՎ=tQc_)M} *4{NyyTTQ6;jz>`D}T)0[1so8ϹwppH!.5jqmXϺַ2yTy<~YpNxϻ]6sW$aR̗#ϼ7y)(8v =J?z698:TLIw{Yh`Ќ}XHY9w)dB x{jYd'sJ|zx~ڦutq=D`x;=:@ǙEʉe(:NڍPK9X3ځq6Жqgګv.`oXwo wIh$*[wo٧ `ࡣ' wjwӺwx)Z /ZBPDڪF$ْLO)i:/8z ؁zx:w8ޚf@h8`*wʦ{%vfъ;rߪw ZfQڂ:ɁꚯY,و3 [p xڤȊzyBQ;9ȥY .+d),`y"`+w)v q+IȭYvတ"H AYDБ"k+ Cځw!u"03؎;u1@N+^[X_V&[h)LoW; k`Vk{zwwOwo. {[Kk+oywI;+صom. 9`nljۖH8ٿ+jtpl#ɋ`8K0Q3\؟V m)+,ti*:\=kE>X0O6<0$>.4umDn< J&MEw}K~,-\>VbM;h]G0=c)X8 8jJ .B.è熎y|:Շn1o.&y^k~>=0(.^m>X̴>ϟ.߸.*mSHul. >>{w,ЮԞ|>w_ xN^{ȶwފHv&釀)ږo z,imfhQiyh 2|2 ,S=6-4}1m["N(ڡz k}FwʞR Xqiuhb½*z^˽-Ȝ_[Ւ 8(L|PZͻa۱|k٘G`mmYnPkٗ;-IYvxOjڬ/[wb;wª ,{dzԭz퉣ǘO~mv [w閎xw\/ zyP=_ڭ́ǝ'hp[}`eFCHp Eh%(I(b%Hi69(:JiYʺ+;K[Pw ,!(q3MB,GT} YQ7c$n*r%h Kf6(f(S~rœ [.{K>ݱ/գu~]VrG ֬ح(2?.nPa7OyUv[`),fc51ܿ#Jiz{E lD4D䁌u׭]|D!R.tDd<IHbW}F G[b3w(FFhbJ.$E(Υb,, Dh!s.!BxED`aqqch$,Ō!DYID^"#n੧jeD0W(聿Pعd~'E17ʋyE[pqcz! BʦʋwHtڧmc/;Cwk,*\D /[| 8\Hnr&IN) +hZ/"BW ([\AAs7 })$/l`'Ljg|ڹ람rʨ[һ,W8k33L_ BČRKG-<]\)rbEidL4u۫2keym[7ڇ-Dl톋8?C >+Dź#⊫܏ mҖnѬ/wwBzcκeK2uƐ[:`P~{0'/;4D| f<4g+|s}LJ%7?'!? /ֈ&+ o`Wt:B*#2[@[>w?x;>P$yp 0eEV:G<t%   """""!% ## $$%*(-).,--3/0.133398=9=855515=87888899999:;;;;;<>>>=D>C>>A??BDDCCLUUU-NN:@@:AA:BN8HK>EP[fffjwwwBBB@FGEEEFFFEGKFFJ@HI@KLFHLGHL@LLJIJLKLBHSILPLMQDLXFO]DPQDQRERTESTEVWNQULSTNPVEWXORXIR_GZ[IY[I[[QPQPSYSV[XWXT^_^]^_^_T_`X\cR\mKabKbcUbdUcdPlnPno]j|VwyVyzdcd`eoihiiozyzntiwqx[[azuaffklqqqvw{|ɂʥɭԣفӂԆޯ!! ICCRGBG1012 mntrRGB XYZ acspAPPL- desc|cprtx(wtptbkptrXYZgXYZbXYZrTRC gTRC bTRC desc"Artifex Software sRGB ICC Profile"Artifex Software sRGB ICC ProfiletextCopyright Artifex Software 2011XYZ QXYZ XYZ o8XYZ bXYZ $curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km,>H*\0Ç#JHb xiȱǏ Cz@ɓ(S\ɲ˗0cʜIfDɳϟ@ *HAVHʴӧP"mSիX&5煮`ÊAUhӪumǯnʝ,ݻx 7߿cLQK +^T0ǃ eT/k+9n͠;M:lgK;z먧צ~M[mڸV;;o 7|Ro@Nر/Q;mo%ӫ_Ͼͻ~x[>|iu}%r G])haH՟?^ g>H Z,~!]]zH$WK{#GCIQbz'X$~uH !z@`> YKSKc)VJ\],+L "K$"U`qAg4tGpyy`V(Ef)Wy2+`0(RKb g.X*h{""\򊲥fnd^=iBD.wGU2&J@^`yBJ'׊^i\)l^0@.3H2񽮸ҠBrI S^(IBΙ_~muY=in']BzX\b#y yRӯMXbiP\PRckwe]IȎ@ryNw.4oz@ty (y$ǿi5Oh\m/zVR]kW }ĎjjCl髇,BJ J-Q졜a (!̚B%mCq ñC ;̋} RЃ5ϯQs?_xQ6دk@SFp6^,Sˆ6V7r- $Bd)V@~/ae1 XfI<K@|ioxn#N̡Olt=*( zqWlxupE :؟>80q8"7 y鐈2 eIT#I$hA6n$3FJӡrcaABO+C#2jk 7Af~Ќ%iZts`-@af5(Kc͖ KӲ^@J0RD#k_92$7cYlf9yҜ`DRHgV晕z i"/p PA)C7Rj#/x`J&eKնdž%0Jh+ŊGwτq$ȋD")O?VӪ7mFtZAH(p&#)smph &k;$X|S1],9Xt e_^*R{̼_e>0~V^2̙Qp S&hRGόM"$OFzjG1giiP $VyA wHGGGgtB?2zVc==j^Q b%*%@)L!ۏp|e[^*m msZ|8 GFKѴg1 &@b, f7EhZv7wjn7WwRo{ܦ&P72aS"6YА/<yWr[{$Lp0 S7fAaNskYn#(w,I7bҘB._5̩-lUۺsY& Yw:춍U iScWO=jgE8= wЅTRwoM%UƙleXMnOJeAϒwDi:@mG29rxlO Jkq )={e~-/!=]o0U t;/|ѽkD ~nh~)!Al^ b6Q*Q؁ ")g*,؂&!284X6x8`~}$V0>H@XceRr&GNH-PxqRhcqrv-ed[gȃ!1CQKBZv(^Xz"r|x"jHx~ȅbш@ar׆f" $M (ъ'GX~h8oX0"(6X-xx~\HDψ8Hh( s,8Xx(LNAg0Yy ِkY<ыM  "9$Y&y(&? Ƿ04Y6y8:<ٓ>@BrP? LٔNPR9TYV9В29`b9dY@Y;@WٖnpK.ɕfx y{ٗc5=:Lr٘WI[ H9 Ix`p50 铈) )P<7i :isٜZYvgM2I :@5XP_q 49񙓴@0Yx @YX0PZx^9 ɞ{@@ڡ yy@p>PYx^٠4i  J 9PJ0 9   )Dj7X`  VZZ@ jʞsʠk C Ypx`P{i {: Ex0 kɛ4y ?UI @ mj Nѣ:@ Př 0@)I %ʥ:ZpIP :@ X଺@ڞ)ϊ : 5PMZ`rrTI>LJIL Ki .ʯɪM"_٤3٤*!+ t5YP[6% '+ٲ1 ˱Tp13 j)J* 0 `Y]+ 𩏠D `PɣI\?8HK{ J/` cjYij 튜U:% F˗ߩ :5px5>1Q K;KY +OIДU;&ڷʫ۸{ q@kʓдj{6뫬Z)ZT: qᛴԫp:9)Ca @/ pۻJ `K ,NLp{kRQZ )0{Y0Y{'l*|j[ô@ ZZ29 |EZ!KY+£; <|ˡK8 !BAOi N)    pr< "L`^Y١4*Y0p𕊜i̓@ɚc9 q@dДJ̛i 5 q?\j۔KIܔ ̔<[<[I)j\L , ` ̔~lʵ KKi3dgۜ1i|=firkYǑI%$u$uK&d {* M ]MNm@BMT]F]|cx\iHU]E^n` Smv͔WH$ ==΂;?K>bwͣX7Y@5 +7IƊݓMzÞz MXbsu e@oTJн4雄Կ Z@Y@JZљJ9zMinMԴǗ|幠y:eJ  i@۟l]]7 ܯ߷l-]ʡ*_z]]&Ly͔ 64!Chۦ6 r*u:gp` Pgkj<@pދ㠻}@Kq@"{N \Wj3~NJ =t]Ty̼L@ =k&nnT]J=9싫495ԛ79ܺIʌΗ I[iLLٶ/ {v {Ϲv<k ˰n3yj}Y͗3[;~66͞> M@ T Ÿ+^0iꪲhr>f[.t{>аb D` {_e{i˵Jɶn .ˇsюk)q` 9n M^-j i򋛴+P-Rǻۻ UҽO,û 's6쉇b;qΒnN==^;y |ɦqコɾ";nllYϔU ͢,PGLq|T@C<6IJBLAm=D Vô a:ȿ_|i-k-P܎I0;/;x}<! G"@PH?x=QD_,QF.tPxtK"\$Y֐3Γe(H,NYC%R]AgTXs'8@5 5ҨNK JQ3idY"3uJU8H F' I uG OF% G6qGPhbB'?#NPpNjmx["}\pōG|ou?Htæ"p΢%\2ŦL wT219(S"4&U" gfO!٠6AޔcA0/: Q!F ڣl?@-<E$qCʼn8?V4!;T^Ѱ/@"u@A dI'p# - 2K-p r$\I3D(5j.٬2N9Kt,3M?532O3QEС#4=3PK/ tЊ t#D5,<N39,`UW_5VYgXU rW_/NSQEVHG4؉Ru6Z v6dTvLnϭ8.ŖsWQ]K\~ _gT`a8b'v7X$[h Ζ$(6j ;wl ]HShKB V0[$(}͹i7ht۪/DxNB6ltzݵ[`عݔnh@kP4Xm#zquqdkqxHZs6 (羜XSHzh)(P(AY_;Sg/#(A xo3:5 _H'9s??x _(4{Ag0"#b@ jq1[ٜ)uBxƙl 6HUPL AQahh(Z yPWx-dќx!橄."2HeHaEtIa5D3qk_)4~XǢuMn%>ьEs!~>@ۤ /E4JD$RS>*ʈr,'RK^l` ?'Q! y7]zFIiF/`2;L$ϜDg:չNvӝl9OzӞg>{hӟwqHDhBP6ԡhPV^F5QvԣiH9ʅk\@DnHlZI;B葓"TAR"h2I-hӉSD)0Ev@LDu թ6`\ShM"URTдxQN U&jJ?Ҏд PQ:AuOm5;Ng jiTƲՙkE*<6{5]Wev%`gURNVkǖYiv՜hUV"o ܝVvݪ 'Y1wq%qg\h~]uZXrlǖލx^`7DXp5aw Vp'LGm4]/qeS`nw*V"X7Sq&LBrOFh|ީxB, ȻO: .N6ל6TnPe=  C'QN;X:ӏ(p#OFDndJ(]؄mamz5.nu ()>rV!54!>EQ8bG1H$hBF1b-ﳽÄo1=ʪAܓ L<;.Jb@a/k@ Ub2ad69&;w8ߛ#W$: .ßO?S=):"r=(P'J]X\@'#;=#P$$[N[ A\= t2u벌k?.9IRAe+HHe[y+'4@G)<6@ T@%ۄ=pOh2O LMh:±$#;3# q # LYAG㵊4Lu#= N(+@Fc8?nI?fd.#=p9;9 `;z2,|ल5TJ7TNzq͞N'@(N;DVkN`=I^p4Or3HN|  J%؄U'R?hN>2WW%P,E$==JPԃ*uiM=81K8KWwK?eu]vw]4QR݈:ŵC#Q=ߛʁ섿ETJ|)˕`"y{޾KDKm̓ P[?SM\E Plշ%LΤLLdVFv4$ JN ASsN2 ֈdK69\d e匐䎈S LdU`NneG~ep[&fDNM^fƫbF;JfYffv_ %ap@X)ffmDguZgSNe]e^VfxyFŖtdt0gPz豉h茶#uRfbvr牘e(t闆阖陦隶ɛ靮Jez¦s旔<>Pj>pj^nꨦꪶj~v;ꮶ>jfjk6>ԣAio2f"-$ί%jy ,4.ש.F6!*)il EM,rlhl ʦb ' mFNvs*Nh~hm.,֜ Xikxmmv%M- f^Vno&oA֠^N>ŹnN* `oooCy.>1ofOG nֳ p)q_ O*7p7ל qH"Po %Sqq ?a'rt1'' .r,MBg3G4Ws(r(9:(?t}"B7C1 FO gpJq r0&.O$XS nRN62"QnWw6OY 9Rp]eub['$Z?jfwvPdw eqQ+kvh'Un_o?wl_o__a^&swY"ig)f{A.kHYX$ygr؀)`xmSGwEw( H)HrDbр`%jo, IP XxX_@h~zz)@( ܸV_xR]`y]Bg۶Hy{^ zjG1kz j ( x"O 8 |[*e |%煮1Qϖo!aXay1iϿmȁnR/|s}ar}lRʍW~RA}laya}/w=_ f~[LJ=(PO|(o}z/wڹ~^,h „ 2$@Ä0 2 G,XAŋ7j$H0c8%8J&/9#.|!(Ҥ(2m (L1>jO/h)PG xz1SY^7 К(e D@Z^gGJG <}U[鋰X]LʛȒ'Sl2fed3ОqKS8(  楡1pj8;(KƏٵ _ԨMS;Ǔ/o<׳i֓j`?_dl`̴A @^+qt @ `ƋB|֜F0_Renܵ"18cڊ9Vv="bx$I*y($U?" MYI}M.di! WNfEB5'0i^{٧zh ZIfzfb%R(i jh'ޟ3zhwhĢUhj*Bf*X'_ RC(5wD {2-j`r^ɮw Kǂ,&I}zGrɪU:/WͪiW ^{h*P;mI(뎩 !ѭx0k0j ä&ޅI( J(Hp" c2A P ,A=c㽔 Ծ{+f۩ӋF-;mzj񰗔|-M.\-#UɋeoCu/ Ti&-iL5} '5*k֍G yֻ‰FrB KI 7ZI#z_KB]M`EdpӰF Xbnpx$ĞN+{4t #퍸#~||1Oe`٣O;9=~\o]H\h`[h :Y0؜XPhXx(!rhT1mr ɝc ;A# Cp$,E* I$1Me Up%ٸ2&&됙e"pYb%瞀ify fP ('虉&:椟ae~(^J䣛頨jZ)E*묢Z뢙J[i(J뭸}z졶!:[Z,R;rق;ۚ j.Z[5ڻҘo,{!{溢*NqoKqpGQ1rCsW"%)HFt 2*;yrFr(.BS",L%B̄Bp;/tD/a4״OLLQJߚf 3vc p#]n=]nΫ(v6wxupgt)ί_jiޮ->\=9эy斟|.x{d~ݕn]n:ikv;8g1/zyKoB}:m?|ѯ&Z|z{νԙ_Cu}9r>a|sߒ=On,x *.| l hv} 8B}4MHAw3D=+ lA$*qLl(JqT,jq\0qd,ψ4;c++-annotations-12.5.0/html/iostreams/0000755000175000017500000000000014466730207016451 5ustar frankfrankc++-annotations-12.5.0/html/iostreams/sbbuffers.gif0000644000175000017500000001461114466730207021124 0ustar frankfrankGIF89a X؀!, XH0I8ͻ`(dihlp,tmx|pH,Ȥrl:ШtJZجvzxL.zn|N~|KeHVIFG4E"Cı ޼ڼ Wql!p HqTBr 8|(0#=VID EFH#0c*:1%ȏZ|)O@49ReПH9&Ħ9T7LC:%e8WÊ%!U7~:[.eJZsmڷxR"ӍP ,oT;'K o*ǘ3ґ%9ɻҒD*1yG A\d$Iѕz^.4]0Q7Lu4e/5{t1WQVSD]2vJVқc4#JYƲld6UͺuS7DN2\'릩@li^הv``7Xt4 B+=TFk8ۺYv\Yku?;>b8,OaNնLmb]X6:mSi[&Ը`E.4 ӹ.!Y٠Zwحnv[&ջKV ^ֲ U.YqkvկtAE}^!2n=;_ٷ5-{^0L_ X &mo6zݍolE\7o0U,X qG<pZ8%\a";w` {YCrE1`a\{\1ms27q>t=/Gߏ^4=AOM53%,6ULYu__zإ>v3{ׁ..4o'{5GX?o8 G*3~Yw9<x<6^7OxrV6Wkyt^oj>AXTV}INF?;h{>`}t">{?b/nOw~Կ w*Ax  x  5bw$4h)[0{Ò0A}a(O+y5'fb+uB,")"H; $(8H-j)Ѓҁ^!68%"|aPqr+W/yZԢ)C(it.FHB'*G)f Xy8e%Axr,wcHLH+R؅5l{ ؄S*[҂Pp^xp&HX Hzgz}N7@8XxȘʸ،؋Pq-g/X#UqK"/--( 0Ȃ,cw2~w!+9s2)&x_Pݢǐ 99Hx(H8&%*b#38w:*g07ؑٓJ)+KXȑR$Ti5IL[ "!fɕSinq$jk ^ɒLW0s/"@B:DZFzHJLڤNPR:TZVzXZ\ڥ^`b:dZfzhjl:/a"Ѧ0}(X/r0x: .|Iy~:3מ~¨PqQ,ىSj ,O7"xB|)AZ*$(uzZ 8º Īʬʬ*͊ JNJ\q,:ʭѪj*犮jJ ǚ"Z@%1JY੗Q˰  9rbXພ {/x⭼:zڭwuQ+' tz8wLwj ʳYF{L۴;RK[XZ\۵^`b;d[f{hjl۶npr;t[v{xz|۷~;[{۸;[{۹;[{ۺ;[{ۻJ};[{KrSCe4dnkqqCSomkSkDD[9lklۋG{l=;q7Y;l<Ľ{nnږq?{nhg|Ŀ+ [ ,9|f{˾߻EE|q!\9fH < \T,qlJ 4,AL6m^ pOnTG,pULp*i ?2 ę=TvF- y=]_,a?vwȈ+,:mLlj&bk ɏsȍZȚ|[āÅLȒ ƥ@Ɍʝh6Ll|ʢlʞɬ˻ʨ6˲\˴qL8xl͌ż\<ȷ|Bl̪L ̪#&lŌA ϭ:ŕ׌ټ[7ƟLN \N= L<լosl^Ϳi]M!dS g|;(,};|60 1M3M5Ϛ+):2mF]|<}$=֡[ F - ֠L̀ѓ|^=w"Q&]q}sm5iMOa-צؤ MO}هȍ-؏ّٓMky pjd -԰]Ǥ>ЉmۋmMoہM ܌kMz}xm/TMKmōݪػ-րS=ԗ\ݸ}ݺ=׮ĭ m6RMmޭD]- m:]Ԣǭܨ^ʓW -Ն%}SM#2q =~B@=6< ? -M:GI/~#MmN:8C.TNqnn>l]}N1N3(ޭ D>Au~V{ynݗʌ.>塎ߔJmZ`^.hj晞;>^f>W~Kb&.>^gNN[~؞nruG}l. Q Tz W{랎.| Nht@uT8x|>K t /v 0r_}/vxWw~ 9x(?02˕1_}(uؘhy=TA`yFLO%Gi7 VXC/#4K!~M]/prZivOs7.^k]e_Rߎݗ0 ֗X:Ggos!?,H0|ɲ |i*8`,'g0 oot$),?HWhhB*hOyXx9 7/&_-*C;ʾ^ڋ޼AH扦ʶ.(L=ŸGMƄANK*W J&֬_K ZW;}8W߹'8ChxXبIy7Yvٙ**ZjBzZ +;K[k{ ,N^n~/?\֔J?)S@@ F:8 D`F)al#EFY{d~7 iNJi^ini~ jJjjj kJkފkkN lKll.l> mNKm^mnm~ nKn枋nn oKoދoz;c++-annotations-12.5.0/html/iostreams/ioclasses.gif0000644000175000017500000001434314466730207021132 0ustar frankfrankGIF89aXX!,XXڋ޼H扦ʶ L ĢL*̦ JԪj Nm '8HX!ȸh))hy8U):yzJg*;Kz[[š+k|L<\ \X,=Km .m;NyV-D_~0`~0T1b =1r^}wQȑtxɕ,CPd]Ȗ4kN;b4hti3)MjB0SSαzҭ#9IQʘ&ǒ-UVgr}kVb!j2M*7``ୄIY:n)œ^43f{Sѵ Q\Ɵ[K\e vjXE]V0K .q̑!Ojy齞_CP:;^P;C%zvU|{L#oɯ5 x * Ja-! :xW2!&]<za}h&^!b)8T2p3޸ċ5cFdBId>H.)L>yR6e 9ie`epe)ffinf)g.ډgyy9 |I.Z> N^jniBh*jʘj@ꫯ*+֚ꭸ뮢bj챔&,6"*Vk-fv+販i뮙+ziZ櫯;C)0#)/ԁCRQgi(o,R΀$K)2}'lL|.C~3>܈: ij?3="82ȹ^05a,`ϙjwZR[6좮avjB_DP^OI S]x]#;#?xՒN5gw,CvG@9˽Ky 4BX3^u<zY}{Khú޻O|o.}'[|,_ľ=dmK9?d? tžuQFw@}t׀BP|$a=r+Yl(& j{kW F/ro8;΃׳_D-^4&L\ Ґw#^?N3 (.r(~"HlvS&s'̨Ґ7bاQD|{ݦ?rFC1"A22z(y!KBd_8I`{<"S-<5"gbSF&خal89sB\g:Nq~F;HusD r@7< E`mA qX(|Y4t3D(GaQ`7@E/шmc8 b:,|7%FPb14\tDΧ(M1J3P=Sѵ=^T V:p_"Sֳ2̩jNѪUNqMkAfӹudM"_ʋ>ƭK$j^W9T2֭e/_"1gzА}EaTЩtMbk]j^–l_KdCJmVprQXS,kMܝt2֍bBn ^Ծ7̭dne/G^vMXӖ׾A.7iS&شt wW ,e_>4EYK]8+UxׅXĠ}1ZVXx%_E.1 dzS4ݙv D^!Z.rQ|]&m0(ĜgfFAAf6 ssPg*Ywϛg;Cn9htm}֢EZYg*"LwHT!U2!LnGcz~`LezAl.ʵr*<tLկg M;^-w9piO;N\ ~;c]*>bnOWQ2AWh6}Wo~Tջ;.xBBF;\N\!͋N4ml2$kM#9.{sFc9;G͏tr4zS[տ4u?]'zٕ~v@aoKbAWL].Rv-ƲIXR֖]?ċcjnz|d/vQZWm_q1\W oܤtuu[aPƼ_N>NtRĹ. ,!g:^p6 OCh_1׿o6}ysg}igcxd'AL7GH{w~L!wwBg~q}zq6xё(KXmHs6WQTwUl(;r{v1x5yuؽ{t<H[{9f1{{aG쫿'v\Y (~h< 97ڪ{ w{-`zCPz 9%x˽CRVc{GG4ďxE\ yt$C13|G};ziܿؗ}ʷ],hILme[Ŧ‚q,#\zLl:h}{,& {ƹzjL'E辡 ɝ[P\ʒȟ<(MʜT Ø[ KǚˌBɟ3s'Ȉ ?\D<%Uƫ\F\QX ΪǺ,~RhSlBی DZl¸ EH]6 [ } "Ƹ\%L|{Xʋ(*&| <+}_r}(} lR-͈ =}{b,Ӧ܈&u[#Kk[ȪaiMp=r-֑8rxk kl}jv[p{ؿW\{؍Hu- {ٗmيٝ<ءPiؠm: ٫}V= ۱=7=յMўMگ]s ض Hĝ۰].i٫c]Нܕ8ݦzƝ}ݡʭMt=ޜ]ֽ]ݰޗߞ̝߫ܝ|Y# --߬ū0ndk0Q5j$5R⮑u⸲X5R/u㳲㮒~p1qrR\[J䀑26q5KQ奲2S’r+oO,huQ熦{n~;}.&^dnw6~茮NNBnn䍮RNn\^ꩮn..$赎屎 뻎hNN%N슚yn뽮1>Nh΋ٮ@@M.gx$ Ngnz PJ?O ?Ϻ"_VU[ ́Mh5-ЋNOl̹,- ŃX68\;4Їζ-OH4 JM[vӬkL$lP]R= Yo#.Euopw{(} o qOyo/?oO-&F2__/?ȿ"үԏoO/_/o?OSF9igy ő,31Еm噮R]T.M3sNUH]cV_ks}/gqёCQrR23S3rT3ԴiTu56V!7WwW6X-9Yy9u8:[{z<[|>~[ޞ]^_|aB 6Ԫ[]jkX$qiVkTekKlq%ޒs}3PWy`ح~ =odM&|.ˊ73|RrhJwӑ{l鼂IvVtlG:Iƪ_c,!ܵU}2fΫ{e+;c++-annotations-12.5.0/html/intro/0000755000175000017500000000000014466730207015576 5ustar frankfrankc++-annotations-12.5.0/html/intro/objects.gif0000644000175000017500000000341314466730207017717 0ustar frankfrankGIF89aؠ,ڋ޼H扦ʶ l" " hL*L JϩuܮWT0ޙkK]koXh ub)9IYiyii():JZjٹBx* k{k+{%S ELX*< jL0" FL=,< Fw^˽^ξ]>[~ iwmpx)C(N]@mDRx erMVx#l#QpJ\n@v nfsYlIgy^ h~Y.h2jM@'@i2饟*ѩQꠧ*hΪH*D1ځK,RXbR΂-$Nܭf,V{U-96MLyeOAt;o 5ˎ1poI4B.ƄG!-eG` !\zsoI54]Jy 3hn \q|ƴpiK帶=5M VafpPniu[φl J1+5gWqY4]FC.6vetҍ6[Ӷ 7d3TAv_=&P>a228d*v8 *Rzt.\H/{s{4_>ϔyzS_8}z/%_Qr [lMKnh@߄ xT*V<@J1P,+-yit7 V)4!aB 1$ wU0979Cn?aC_0ITbeቒ:" 8)Vd"ɳDCmW]HEWegF:ciU~{@GH`QQK" y%9r\&I>zl^ԏ]Jhn,+(Մd$rq$:Y-A1\ + 4LV&Cl *򂹜mm23[$ 0|YCLJ&s8-RKvs3x'V0Iқ g(7ʥ-E9ur[[^7A33K_z%=iOנ32TZ)ǚcبlʔjIm9/ؽr`%uPw:vNwJΗ\jJe_'#:@QS4 *- ""33 #$$$)))((+)).3""1++3++)3"7ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km, H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟ@ JѣH*]ʴӧPJJիXjʵׯ`ÊKٳhӪ]˶۷pʝKݻxk~ ,p0a]8a‡ Ƒ+ùϠCs6X1҉z既cLڴfʦni¶':5ᙇ6,A wqسknp'{'`5~wNO/%th`C)w|d܁Vn߆Eax Z(A&yq8!0ƨ2hJ4^Ec Ax 񸗐1מᦠHVr*JNca灉^{ h噤6ߛp:`r,ɗ|矀ʧWZAũ(N(fbhs j}Z&nf=NJi ide]F){Z {YY뮼+XZk̺B6+W=J[JfN˛+-\ꉞ'ޒɻ+vw>&5,h/܋U[b,MgZ Gp_ElϭZF{~ܢLey3ZM~\-7{+?#mL7PG-TWmXg\w`-dmhlp-tmx߀.n'|+G.⌣Y/gw砇.2L[^ꬷ릣n;9\qNK"?<-Oι$†;cHp0 C\!>0}9".tBCx=W8A9@/׽߳x>s+_-}zRlf smH!jabha8#a"̡P` Iȿ"2`o=a暷EZ\\1g q/V xEj9[pRb.Mh0Ld!1O! e:E-Fσh"9: ?%ΰW0*XTRvt(YIeo9p]NnN}3=L҂P{f ;f9^RDt:wG[x_ιuvWW!hΜP:+PM(@j&:`r( `@4JҒ? ҺT,mhS23=MF?KB;[Oust95*O/ԥFBe*TӧNnUU*խ-IТJֲhMk Aj\J״5*n]S'׾ `KM,`uzצ5Mb"L,f7+X6v)C"C`e FH"bٿjm$15},LJ7p@ -: E!/@NB|u.t[X/P_ XxAB@ /hoAXC!hm΋~7-yW"aXCV!tWUGB6{ WߒUW( H'nz< CX@ eZ:liZIX0ilc+B}!I`!5D㾪.+589ęDcbPKEdF=zW9$Tlτo`BDXq[ _8,󻌐#Y^0$hbF05V=Y t2k BīhBW_l[zl/7a3;*NĚ^x%Ҭn5?,ݝXw'41#D%`mz{^%./x+ׄ ~p>5$IYؽsh|qK[5} C8xAK8fD~ܖ XqZOue#I(ѓJ` %Fmtw $ӡ.ux%a&-AZR:NtF_; .aOKLT8%B'1qL톀Ɣ>x JneX~~;n_~qFQ^-1K_% kKݙ aS7=wޗs͓|_e~qCx!F—vvkv&/vGt.I7~ɵkw5sA~ Epx>wXYWQG؂ww/HȂH6uw姁Uq!X[:wLX)N+8/<ȃ77F0H}o_w g.j /SvFwpghw";a~zUM؇~Ȅc#AgnQ4t$0'{8 I@@GfNgGv0{${H@jҗvw䗇DYqf0h2xzYbUW(Wx @(b%9nH9׌Xq|0}P਍(h˒Lð Hxk))'_ȏ,2OÎ혐+[YŐNEbV zW4i/DYZ5[E_}([\|%4')#~ee`F^^^WH9`0^s_)XU^_]x_Ey}` `%f]֓E15[6dd]v]9c4iClW9 EvdIr~dtfSvhWe[f7!pui&iՔ$c)h̆z m>hh.gv^vhig$Ù|!eU&s~FcesfmÉ%X&yW0IV|5s/rU]Js;w[)rƉsrXhNqvo'Q 68_9~i;3H /H,-8WLxue@k ;mn\T(xʰL<ͷ4xQ<:,|h(]._8VxpX(W֬vϪhjܛ UB; >S?$@_@=֔9= Tԣ,v}׉r9A$BLDF$C+TL/LMCpDڣDA4.^ q gAgePWP !,..>@>j!Sh- ?`L&qM6olTeV. >Cb9c?@4>V?>?Fg}. O,@P NʿPPPӯL_D, , f ۿC ,0,O , Qƫ]łfp‚ -(0LF=~RH}DRG?~V #/^8ТI^98آ'M6pjPALf-E&E3(648ϞdsyQJF@ub7 ~.%ADž<9Xe~-l) |胱&΂58 օ_Sj0vӞ;7r/M6et"g ͑gNզE Ot|;?>z <_r~ 05*b@ (J B H@740@ C, DS1EJ2螳1Ǎӱʋ/(;DR!4X>O?Qƃ< [Ĉb1D/#Ž$8O|3FU,PC741Pp: m&(Z ## (Ly &jRnNP-UrMk|Nl(4+ĵ54۴L7^a>֢ݬc5³WhsOf5vσE[C]:rp` 8p6;2(w9{կβ+#mr!W&XOW ,.p S0苅+d D>6" c5beVcu+"ca inY%Qpi\,^:jj՗k;lux'xG>y协ny矇>z駧ݫپz_'|Ϗ^OR?ۇ?~秿o}ԧ?ЀD 86Ё=FЂ`þqOaE8A zP'Da HB Ѕ/aXx І7afHЇ?WC ш>xD&6QIT 8E*[b^Rbh@/.cDcwWF3Qo#83юw  XG<я̙#GB9!Hqdd$%Dq$%Lv'EIHPDeKiT$)]9K2m8Yҗ'ezKbj0„d1iM"p˄f!f6Mnvӛg89NqFs~T3ENvӝg}ow-vB=ivAob 8BNCŷIp7EmC*Ut"ZrA|)_yɶ t*lj({yA_+ZeT/ i.׌wVavUun%{.=cm>P$'>S3pt**(UCxab]g< ɃG8ճAx ޟO}GV_ֶ[PEd/}7ߧ{+~VGJL?Q8~W?/ -}p?={?#$TTԼ 3kL* > \< @4῎@S?HAh@AArYA $#ASB`p~AA*A? r•(žA0#BJ-9:;L,,$ȚJk4qEHH]a{*;-,[u4+۵Y(2!Inlʥ(142D-D>e4'ɲ|F#HTgI4o Ǥ$ʤ4FKI49H֒4HNYb?&LЄMtFǜLhFDŽLLlD˵lLMKL$jlK$w+wsԺˤH{-L4DSLhbN#4# $0Ngf4#NdN#` Mi(NԄ#0##0DOLh4$#@NfNHMɏ`MF1̳֤&T5S-]5M[W8cLKH܄fJ(N0Qi \܄̈́EɄ LQuNuO Pj)uQ^c֟^A?x-3ݼzs b"-]Bh;(=)9*"6o `G`cc#R05&aF78&9:.a?a^ܭ⤹b#($Vb?`b'F*)<`GH$Aۅ-b^O=PI>c5\@CUD@f1Q9B.(\pD3 &6i0fbmfK:i.iNi\*li >3p袞蚾hX_8ShhXjfja8XjUw$IΑ֠&h.jahkNnk.h R؀h hSnYh&hfPhh0˶v# h0ŎjafmfR mnmmn>Rhnnk?8iaxn.kmfVj~k^ooafong͡Y8Pvhgpoh o~m N Ơ.`gm mRqYpmi%,pBhj*_*kmhsfo l/&'Z6+^~q?tsVfNq< h@HoA'pD)nIiP^7Mf;WBPWuNtw.SW!zVZmY v^OL(/ dO(Ux1vv$mY_k7qTvtW MpW+lgr9Q|/wZ _yq%{ 0ttWIxy41vvO}ߚwWf"x`S`4' h xԐypHhgWRh` hww?1G00 P ƨ { 7`0Ո ׀{֐[ٍߌߖ7dgg/ɍIYθ  і|y j7\H51!<3Y'O8 xOEzŇY^ ] Ϳb/av_ gh~?D/0zOJ~٘(˨9 Ňi`BC D. jtQ 5 E@a"G,i$ʔ*K"@%̘2gҬi&Μ:w9ʠB-j(ҤIAl)ԨRRj*VJm+ذbdž+ڴjײ+ܸrҍ-ޖz/.l0Ċ3&'Y*ɖ/WۘТG.mԪW}5t=m6ܺw#7‡/n8ʕn9҅.n:CN;Ǔ/o<׳o=ӯo>? 8 x * : J8!Zx!j!z!!8"%x")b;c++-annotations-12.5.0/html/sigfrank.shtml0000644000175000017500000000023714466730207017322 0ustar frankfrank c++-annotations-12.5.0/html/coroutines/0000755000175000017500000000000014466730207016635 5ustar frankfrankc++-annotations-12.5.0/html/coroutines/coawait.gif0000644000175000017500000001660114466730207020757 0ustar frankfrankGIF89a %%%---...555===MMM\\\kkk{{{|||..==MM\\kk{{ĩ˸!'! ICCRGBG1012 mntrRGB XYZ acspAPPL- desc|cprtx(wtptbkptrXYZgXYZbXYZrTRC gTRC bTRC desc"Artifex Software sRGB ICC Profile"Artifex Software sRGB ICC ProfiletextCopyright Artifex Software 2011XYZ QXYZ XYZ o8XYZ bXYZ $curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km,@pH,Ȥrl:ШtJZجv]xL.zn|N|Y|ntqvڄp& xo co*|oÇ{ŋBD619RcǓ? IR! -1DIs5,cs:ͬIM59VA龡E:&iF+\ Bhu]`ݍ7"-!ȭ-7TxAQEcÄ,ta0H0 Dqg*fǕ/_KD ML@0qL?W8w7L{$pD&JPuk M$\㪫+ 9Dt~⵹ڷKm&g+O*>:45AO8Nc\Wy%AaAi!bI$߈Cp0Άeubx /^]8d sfe`@A8$;(%""zCNA5^8/ yhp/]w99(N(@Y唀BWf&i}Wى%X)9,gtZ ~j"``Y:B[WVڭ&p*a}֬-'Xnz굃:FN#X_gvhXvUVhn:+L!쇶bX¸mɉX0{3=#JaL/d>' MW=rPG5_VwY,T{m:O]S`1em8i-0wNzc˷߄w^&3N}S^cn曏عnz|nۖE8@R zx^ "8TTռ9 ,&8Aу֗ٛ {8@՗/><>@$ : @}.yE\@L` 4`}A;p`"؀9<\o3  ^~\ >58>8o9v*L sXwpA+.0$횷'6: gCI5nS &El 0H-6Z4 8d2da:!pI:ꩰzGJo#ɱD<+rdmRKNq(Sy U`L2[X&[06pL:xγ>πԦ`P-R `C'Ѿt=CCtUZL{nĤaOZrfĨS+'1EN$}kO`l29[ס\֨9,@P,HR:8n:iRLh#BT9[. U({ :"ƎY1$ ; M"ًlIbDҗtvMwiZ 82, hL)$g0'=pf^̨\xVC~(`{o `$9@p^)T"lPPѼi):@8(mNwp8Pwۏq@'I{ώ“fqtn'! r֣8u?|>]+EƲz$e DhJF쨨xe< & -A9Iv 5|vTXoJ6cs~#Zy9^ Ph[U?2).jt4B*#A2$Do@:" &@#629s<3a( ֱ$8/rx)GG,]$!8BGODTPq+dTpJs{hȑl&jr/a"!A&`&r&M~m~B|_R&P}bwQw~%{"2&'RNWaWpFxpvXU?(wD(fwGS"w(/~&prq㠁W&7}≺Vw"Eϖk$l;HOf7F/sQ+́+Ķ!sAvkk߷2!,&Nnj #~݈Fiv8+8BohҊpUETj%UDY0wFJ׋p!(/?g#r(#.+Miq./r"'*.qbV:Jh}B'ARU^BCB> CՇ'q9' @pPofAꀖ:kaQ_0 }#g  $}Y@Bxj9 _Yy7-wr38*ӘlDcޠ9㙀 $PjB@L%R-~IB@T}ś AS>u&}` lj TUyjЩҹRd؉cGy81Wy0xU睦mYzWIOwW綟> Q[ɞ@sY It :~xZEj?gjz Pe'Uy:z+Z @ʣڐ#FPCEzLj{6Z8ڤR]{SSڡ=j?;Х^z`Jqb:Zfd^Цr:tZvzxzj_ef:բQ9JŨDeTd:3i QI::`c#7֪A8aSj bR]AĪ|pj9YfjdsbƊcɔr*qdGPڭ:5ac׊cePî!jJdՊezjQ:dS:Z+a `|!jPZ[,[6ڱ &Kf5ѰXq.+frDʲq)+'<ղ8Z=˰:K%1KP?IK+\B M 6*Q\OUY[0[;]W3Tb:P꫔F(#"#`qKsAu[y;5_Y7jcBfZ&{ ;+H!s[w4芰{ˊ J @dn+((Kr{ quK bp+˻˵$ jɻ"˶Z%ػҵ|+ѫcPK{+k۾k[ 4ˋiqc!&ijV|ۮ۽:պkK$[kū雿,kl!&ꮨ1'ǿK{w^ܻ+~ š+ "Ȃ\.l\2̴ƧC˗Ycd+ańEKGˡ̟ %rͽ||Ɵy8LZ |ZÐߜἶ ̹ T{lmL`ۯ 2v-3|c - %m]*/3 3<9e*}JKɍ \Ն'M)}< ՘Ъ`] bmQd]ݜ_n/=pXgi= ~{תׄ}fO-؈ˉ؎͏!ٔҕ}ٜٚԛMy ڕ٢=w]ڂSتڬڮ A;c++-annotations-12.5.0/html/coroutines/awaiter.gif0000644000175000017500000002432114466730207020762 0ustar frankfrankGIF89a4E  %%%(((...333666<<<===DDDKKKMMMUUU[[[\\\fffkkkpppwww{{{""..33==DDMMUU\\ffkk{{wwęę̩˪ոһ!! ICCRGBG1012 mntrRGB XYZ acspAPPL- desc|cprtx(wtptbkptrXYZgXYZbXYZrTRC gTRC bTRC desc"Artifex Software sRGB ICC Profile"Artifex Software sRGB ICC ProfiletextCopyright Artifex Software 2011XYZ QXYZ XYZ o8XYZ bXYZ $curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km,4 EEW^*\ȰÇ#JHŋ3jq!n'ɓ(S\ɲ˗0cʜI͛8sLqP$w JѣHTPPJJjQ>ʵׯ`wb@سhӪ:VT٩&N-wQ6|A$^EaeZ?AmEi"Ct.))[i#^t>:Z e'Ȭ?- oΙ{wMN` G.Ӄn>UyxS᷵Urg9Qn:CxyMƏYe}*m" }ygB_I <_Jֱt(o.('g'֗ AeB4I&x> "'b%H7b#n%cI)v^I-($x ~ȁWZdBe.p@&Oā $IgI%D"҄Tr4pXI'jBq>X( J IZpP:Rg>(j"dy6I.p(Ĭx: 8^bi@N Uœ #*9NIDQTzF4pZۆ9>j'F)$QSI*%gINC#ř$_cDL`UEd.{D%"!SQ1Q#i{W=5m~B9yxsDך>%~U-BΈ-B3Cq4'IS34aUNCX@FMRԨ 8հ 0Yָεw^Mbر[y8 * j[> pn{[Mr#];+nw%ηQ {|Eps'B oĻBE|vy{f?Ns|#/qrhyaNjȼUιw@ЇԼ̕d;6k{饐A( _S*n.{]g6 "8׫1\p(R0! `:X@N{0\ˮO]i[]ܥ: )( "`N(@!bߺ'ؓba> ⯾uC {"Pw8@w5Y0/V~|Sn `B^[pg|8Wz@|Z- -3 FxGzuzgH| ؀Ewg{t=r00uЀ*f ǃFo ChVx|*`}+d-rևx@ȅj|hz(ex@gyFrH 2hUj̶o@׃mhR RX}E0g5 ~DŽh`{;Ppև| :PR'gC@{?Ѕȅ`~~#Xk ֊󗉞 Ѕ"Ȃ pdž͘hWHtt`׍dpT،27jkp똇z [fרQW hQȁuumX'\V(`xrn 0v (Hבm7+xr }^'}|z'~19P}#8췆2ɓׅhpoXF{2qX"(4Y)&{KRI h_@g jM o@kPs1dᖺ(i`w֗juv0i WYyWhiREЉz)Yv N Pk&؅.9 ,Pk)pȌMoWw) Iu [9,Hv Pw k߹Zrp%9 Im :7|p qF8VĐ`* % e5ڡ,* .(!@@P00 YD=: 79 05EХc %PD@!00XeYڂ?u8 zڧE@ su ܅\^9@Ed +ꞎzdz]J] jw :{5PC P@b z 00PNZDw:{dY pwѰJj mHz .IxEgJ{ڪX< ?p:z z{Z8p" ;@ *nhl8 :Ѕ J`Iع 5, n Nj9r)j 209s;[ VG Cp4&״O @+ /0XmZ۳P+{|gi@p[wIl 0۸rik8;0]szP'@;;Jw 0 * 8 m۫ 2ж|I9 : {n눷: ʐ k(; E!P@Ep!#P*6{?㼧yq 㩼(;p 9dbbzis7}ߠH [<7 *[ vgC '~/\tǓw/97 5P@0z%|(!8uFZɁA- mQډ#8H`0 is!7f0x ;:(ln\uЫ<{s/Pݍεov|];vuvc״0]n&meRW/ 1 Mەۄbx 3q=my3*(>ܢ9 K H K} ;w ÅbM; \xFxwpr@ ƈȯ,kyGda<קgX)Ƈ]]G*gǥ'{Lٖsj qIzom{ǩ-(F4m{l)q4[ٜ8n<v4xnj]գa=xJ08\S͎~ٮq.ůp jEpznյ%>K~p~w ,cqM} FNr]rޕg)U.T /np ?߅ٟ{)Zރ78j kp^OэMJ*E-bqunx>}: :q|||Y$Y*$HƜnO&`n脙 g}/hXz_٫~Yꢞ` <]*q|`u?)݋DnuDf`{ğop+&/oqsж0GO@ڏp 0P2TDH SH8IYi(yIx *Jy0Zpq*00x8 jhH[ډʩ ,XZ:S)ܘ+<YH݈=.k:ʌ9B`c^c`2M8a?r0"ұaTT`b v_6J2bЩN-*'&!rЂP]S,~ETD(SVYP':s`?TD-׎JkkHG9dڢ*\o{ɥ[ײEvj.2m5hn- \ȱcevOք ݝV"~wּiʀ<\⓵_z,ʷW[0ǪB-$ 7a Bz*rBY|.6^+3KBUބta"e8! v!(yX㉨"l%~rbHc6ވc:c>#w-'1'CJ.dN> eRNIeR3wEjrd^~ .[^ef&1Bani昖 gvZ(g%tgIIh:h)!k:Ji@ꈤn)(62J#3>t(- z*s7f5l}K) p^^f($~-G4m^j[ЌE+K/ r oN m pYE@% V> qOLq[muq r"j*r.Ljm*c._X Vy)Iit#Jtӄ]sHM8JHL֍ו=re]4W7NPFg@ 4!6@B,YT|n~Ap7V7pI^AԇwQETzޢ>Q R)G|J!/|$s@N(#Zmgz'Qov5 l7M| "R-PB(m `B1C˓R+̓W:4qJX#!UMOx 9?m"pjc,29eҒS*8aEYK$T t#8 (rG"cyFAp[$:71-e.u.13pb8^Q<z`Vt,y8Qg$-IgQc}m1 p$҂,e$%{$R3_YTR=uK0M̫RJµτ jGg37Dh g/V=ŝ}oBSYGLiJkkj|Ԇ; b 8$pO xŕ@O!x4ox< yD.gL@;c++-annotations-12.5.0/html/coroutines/context.gif0000644000175000017500000002522314466730207021014 0ustar frankfrankGIF89a<$ """---...333666===DDDMMMUUUWWW\\\fffkkkwww{{{!%! ICCRGBG1012 mntrRGB XYZ acspAPPL- desc|cprtx(wtptbkptrXYZgXYZbXYZrTRC gTRC bTRC desc"Artifex Software sRGB ICC Profile"Artifex Software sRGB ICC ProfiletextCopyright Artifex Software 2011XYZ QXYZ XYZ o8XYZ bXYZ $curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km,<pH,Ȥrl:ШtJZجvzxL.zn|N~ H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0cʜI͛8sɳϟTP@ѣH*]ʴӧPJJիXjʵׯW0ٳhӪ]˶۷pʝKݻx˷߿e0È+^̸ǐ#& ˘3k̹gɔ_YLӨSհc˞M6֭^ͻߠ Nmq}vУKNسkνËOב'A˟OϿ(hzl) sf1Vhab ^!{iI W: $xh$0(4hc#E&) DiH&L6PF)TViXfrhae,`hlp)tix| yg1"4裐F*餔Vj饘f馜v駠*ꨤV@:h)Fh*무j뭸zoJ᪥$k&첝"2kf:ۥ$ܖk覛#[aIPH@ヘr[++bgZCBpq1+Bn o0\Ѐ#]/aw-p-_>vo<ᓚl)y)d^zrnn`L+uT} _@nKmĹc\A`ogɹ 6p; m |tc@7O-3 yݚ'$w$7 *PtAs@x4Ҏ(źN=\v3Q:= c&1h1\+\@nEl& t> QDd_@mh$1d&.yQ&$ ocrFh,FM+T# HBw\"$cjȖ"'!6@ (bƲZSGǭQ[+Ɣe()Lb{&LVk\<7qf@1U&3͉=mӜ1 j¤'<(|Mա]*{Z5;- D-k[)QwB" &V X$`8`cꔀF,N jQ+Z^rw0U`R#σr;iI9%SiUӺP~HΔ-b|P%IT)TIFkYIQ ݪ%NsL| >f)eJZV+z^_X,YekaM3g(Z״<-B-?`lZRRԣ0kwښQj;# 3Pju%sηղ㕔8N}kEVw/}KZSZ˶BoaF_jjqnh<}ۨ p( * N-9. n h@3?-g/47~-aCgZ֏?gxM ֺd%YdlØeu9Ke_!Ӳ:ipq( 7cy?bLH8NcYȳ^R!SPB͘>'OTA6߉rhnn C %p`P( ҭ^l3Wҧۛq։vkH-z&;K r25Ek Jݥ*vݕ]=;[7){ s3Mт`#Mn&oR_t꧚-1|6,r"_BxhڶWyҮ}lgۜ6wgf9pp HO:N0ҧNL{"J`қF62Lwo bm9[Rx/WE ;nR=޵n\rF7V)tM߃<&͕ dm pai97K2vRXJh`<ش"Pd/{IQHHLhY/v'jZ=Z_ןT%ڀHS~BX2 ";1PuMzb>8*%wLN QdQeV (Q1]|7C5դ/ѧL82R&gZGd-V+(5J`b30XR73C$ׁ‘FG#7cybUoW"yTY@aB&DIe_ l$kG|3}B/Wl *3v5N$HgtTdF6?UPHcԖ,WgYy([ɊSCz6(Q/c65/$Yٙ,'Rёvi$5DVƧq(srIicuNj$xX/WYvؖg_cI ]<鋟`ÙYol :M@2Uecz)MXf.GAiCδTkGfE@)|ٝvoj ,/m9QpʒZZJ :*zYs,I+:Rq4b<:آAIL)>*@ BڤT)OQ SZ\q}/E٥dj%lڦnpr:t*giuڧ~:Wrə˹"!j睂ب:Jѩzj7ڪZz1$ǫȑP2DPD C*uAXj 0!@Ϫ@xv!p qɨz! z*f19ڰg!kKfA$p ! [x[ bXM7&JT1+paڰ|/BBf *$`5ZD5$JL;Q $M *-!#\P֤t:K"Dfѳ9X9nfaAT PȺg!twKI` $@kc`j2*x,+"K;$a}KV90۬{kگkUDհ#*Z{  غ!_sDk$1;Qb2+$RhK$";& ;!Kgs{[ ". ~ۿ57!NҬDrbKK˭« ,߻# `gXA^;6&үc˻ 0ċ"+9"1k$lP\)˶+붮#DeL[q;fa #W˼- 08cel{9zеʿ{"<+1\Z| !е̹ Bb{M+1|K@|B$3 D;]kj5}@=CӄD0mԃJԂP],@VՀ\֗b}jK~`hּ}n=ׯ | tעj{zיz׀]،*y@؆؈ 1j m(-T-̼ KiZk!va#u]ͬh!TKڑ}poLfwفn㚱z&z"![!oAݞZȟaquamA@rd:-k0Ľެk =i+l芳\ߑ#˯:!+fe\aN|.i!0[QJL~7KXYo>ɜc>xngt5\ + XF븈knj(.cKz Lu;[[ 1+!;웻.[Ǭ$=ǝΎff|K\Km~U=K{[~Nʸa(vܰ<h+QK)OrʛЋ2[7\^:9ݼ<%,@ΰ=?!k$f0%oի+-iD% [MKYJ!fڑj [NK*C. BBe(o&;0>SP/.A*PS8+)2"kp >s["=y;  "H=4Ap:쬼K& 8p(/K(B/ K0Ǵ49u93ͤ䴳M;?$3L7SO"<LqIveFG5e@ iw:B #r=?wpv "<\ \Od>$S.(>Vgs E$=y @ѱ"A}2V> $7 a9"~@" t( Cu!o@̐Pb*`A3< 1y 2 @Dh? !@!tԅxBHd9 CœI0AĈ*!lBha`" $F |UxB)Xxi ̀aУBX.†}|p x ,=0CFqTA<>tejž%04A*M""8Al$yى?O 9%;5H`jYh.[2-r(\6!&)q \_4oSLe~d+s A@e|@VKuV9f>(2+ޜ'p2RD;y`CbJQDTj&EuyS m5ݼG`"(1<\2EIWNd&*,E)YR@UTPjjX.)8b؉:U$PD_r5T V: a\Ø8e /&"Q.XSYV;U<.ƵKfؐc mܐ =Lh h*ADŽ,N${@C|Qv4A32 - %!mC RfЪ1m v+-GBI}%4x}>i[r@8Ҥ;P,oضŭJ"'J gB.fcB0H sc]ʄ\!~އxjxճh)`?MQgo,jc~dQߔ\Oάr%@:USCEřё5hGg Ҕ9}*K_]I]Q}ɴYR:Yi]H:ykM:=]l;۵!;ٷ]mxE\mo]nsVnw]o{o[ ^p Wp?)^q_9q!I^r)WYr1i^s9ysAЉ^tIWҙt?Qԩ^u_Yֹua^viWvq^wyw _xWx?)_y_9yI_zӟWYz׿i_{y{_|A;c++-annotations-12.5.0/html/coroutines/awaitable.gif0000644000175000017500000001417614466730207021266 0ustar frankfrankGIF89a6...===MMMOOO\\\kkk{{{..==MM\\kk{{ĩ˸!"! ICCRGBG1012 mntrRGB XYZ acspAPPL- desc|cprtx(wtptbkptrXYZgXYZbXYZrTRC gTRC bTRC desc"Artifex Software sRGB ICC Profile"Artifex Software sRGB ICC ProfiletextCopyright Artifex Software 2011XYZ QXYZ XYZ o8XYZ bXYZ $curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km,6@pH,Ȥrl:ШtJZإhzxL.znxX(~~[qYueErdǾib !g` tV5*\ȰÇ :&!ċ3jhN\,4a S\ڼ-R\0SΈne>hDB4 3r4 cJ*D_*!Nʎ*9t~C .*́-4ɹ0t^pp Ջֺ!0rl $^,ܞnx*@ px{ WDitiRL46Y6C!  A͟YpC8؇ p5JYr߿)(.2! Y{W@|YUXədI!P8 {!:5_` TO3kx%} ]c&b-q A !n @7Ydq術DE΋Fpo 0!h6^Ex#G>b$-G֎V8zSj zـ-"v ]QufUqР=k8*@^f @y8[)j|]պ)K~-07IZ*n8&,`_2;Nӡi3j5Y )O5%y_׎Ce~cC;/)} O`Ė/> 'D68'D]/\W1⛑llu_3YAd;+zS/ ,_ :zy 'GB '0<1<] ICFxCR̤9(H/2Qp$+-J*rG8`d$r<;GJ~΍\\f$Iքű#ռb6Cpmsp8hv^ +=9gtwe[ bbV d0I3/sa|g7nHGJEaAAq 4&Kۋi].0)n"(š/"oiKQ %(G[(U%EAx0hб)g}9oDk@>N rm[t0}`i=Uդ# '9L=7iV#ZEjr8َB7+w]lUpdT7)8lBְ%_oJ*j;.2pYqq}|SVss,i!*]:hˀD>tl@R;G9]m_Xxށr3Dm]cfzі6ؤ>{fGF߸ci)mx3զ0A^}] LEK_SJf>bi>z ];<:Sȳ\|nݱ&nGp0VJ9@txtZNԘ~5ynւӟ7U|m~8aǭ%;+n⬰XX ¸`7텼-˞mhCRM! (Hmk=)KH#01 g: <$G7Lu?EJp0o8@TmS7n7D'd_D!wy?`޵c{ juk|?rqC21/Gΐ0iNM.uO<`YWg{_7~ժmC;Nx" | p{P}՗BHs[ {`[ "`?rȁ uфqr2tHst!u`wz@bH9eȈ\Ȇ(KX6WQЅq)؉؅؄8HG89J֖k( 8 s8ȋ|KxwH;ȅXȉXרRXhcP(-&|x脤ڈx8FɈɌYXHx(8(LJ菂 ~8ȏ`Ȍ|88gC)/9x84y6i{8):i<@I8ȍ׃Li'}Q؏MYVGh6SY@ Gghri ȋ yx/(n 閽hhȖK(y8X"yy9BɘO((y_Ii (o醚ɚٍHX' 障)I0) ه雕)xdֹu(OY,I^)z9YII}\ِ rHk܈~]~ٛiHx6~{Iמ)7|9 z5Y01JI/Ȣg:ڣד>BZ@FJڤN)Tz8zXZjA;c++-annotations-12.5.0/html/coroutines/fsa.gif0000644000175000017500000001575414466730207020111 0ustar frankfrankGIF89ak ""##""")))---)33-223333666661==8888>>===6DDELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km,  0ká˛ҧ޴IP 2˞'*\د dPHHŋ32)(T CH!#SNWY$13sZl%:NiSN:y (RD;TRVL8*3T_T0a" Ϧ*V*~E @{~%f*d`2;UPuLD5rDu\| ze^RY9ec_PXExdh8^^f̲33A8r؜8 wS ؀fnY=CKVR[E1\|p( ~$Cxp^*)$wWEHXthq_~17)[p(@W}!MD>)D9$F 0yM> MFdTJ9\v%^ Pd6(W؊Y(, jNx=H㎊u@* Aj衈&袆J*Ђ7gy.G[}`@g|a ى')5p!*>0@ h ]i^*Z"٩*E;JT謥Ez8>,`d}lW*bqۗc.y FP[ed b|>NlXAְr<޵xQo+TdbNQ(rQpF_țpCdq #{RrJ^FVE)\3s(Kr*'ZFL4'[sc3kP`{3':wT&q)-4jQCٜؐ~t_)%NL4 el'eC';.4yFY]lѴ4`ts9E\@H6N輬, *H(jw0 X [=EKw> _DբG@]\a@nS^3̀geؙ tPO!АN+ <#+H]|h(NHo4m[Cl0,ly~S/sai"zCsҳ6a5,rD"x Ulľq6L)O-0 .˄31PL_0yf&U9#Hx eSΨ5 huJ`t= m E['śh[2:~.~guTzh>ŧs׬rN|1jl~GqF:[=0._;qkz$CXN>GALl3>]hW(I m"p}- 1=<۳ƮM^S{:rFq5ؼ01D{uB3ƒanRP\ L-5*ݢ096+Zs7 |FνWy0λ]cխQeWQU]MQ#OK纘[P. p;!j ),)EX P@W%Z)  5^0/8 j1 2w#4z;.1yt+(G "~a#)Ã#,xڥrTj1Uz 7*9(d01 /),\ !B*~a\z4HJ#ʨ)g-b_P x@V0ZzZgԴڬκ:Z_2J!gBvzs\)!,!GZAگD@)a*{" ~iJ:Y [*&@ ۮK ,@EBOBpB2-aL`;g`Lj ,=" pbHAZPs "B&p&Tc٪VS;"4k|/P;,"ВM;,˴Hq<0_yK*A3?j7ڷ}~{Y뢹!GG{k+~k5ۺ ٺІQ#HK|˻j7XV5|ɫІNWiwث{j 9u0Z+ !34_ȾE|k }x@80XkBT'l|\WM<$&|…/*,0LO2<„$:<>@BVuKfܰfp9Bw{-x}ߟo}~/x|iyf_{j0Xs,QB;ǝū9˥vבգ:σpӢ:"ݽA,4' ;\P.(0IQoTbbLP!@raxd%DE$!@v!6H5ojidA" /iGeAUYsװA$,r*D (ȝKݻs (!AL8޾A.HhOpv&wl׹ugL@Zg"aA RLZj Si hx0@ڴޮ='"Rx>Iz݈r$` `@f0T`p) dvȂ2 IƷBv-\JA+-X@NC DP>"DO@Q"g6hC\b[=6l=- _`i-w-@7Zp&W*tH^tTp.Tp`S9Л(8½+@ȅn+ Bо= XN`w1Hxc‡on £hOel @L@ As1'iTrT'.[_xF(6X%W`N`f6EqjcW1PY"D I3-gx{G(W98$ H`d(9B8ʕ0,% 9Ea65 'T>TV'AHᏖ]ptCxđɾеCn3lCS$zlXt$qf!@s# \v HEc$;fN'uxmez+&RPodiAIR./<(P0mF'lRtۦ>&@y3RԕE_Q^ Ǐ2X<'J!aYBt mY%%+- OOJX3/5LV3Zϊ!ȇP d z hGKҚMjWֺlgK6nw[K}(Z&/j1 siel]XQ fw_Uf 㽆Հ㦷ms߫*6KFuuYOh Ac#*B OAMuבdv I$>a TګCxH24(O7c?},ĉ[Lb.NCd8BG/|pY/sk<ƿ}G_o۞w}_" W\~|0Exw8\aL0azh e_ R&***-.80x4 7X$EփuY:X+fq5rAxHJL؄NN.*b."2}/jQ`///~0`TPN,3:i1fwql sH,02!d2͢98.L}&3xH+6H$ O,eWӶ4[=t4V7R|Y#61^6[7es6i#6(scF#0xC 4Q#@QSscRF(,e:49C5%809g::l=s#=3;0U=ijƃ<1B%;H=sMC>#Sɂ_sA&>^PM2cߤ:M%3C>4@NKj)G8N OxC?v,"ƓOStm,E%4!C,PCpCxkDœDyK;N$E?U,#+c4^.pFqFmdQtPNFtz$dPGbyq兽-`<^B,INr),PI3Kid u42}8$J@ cf+:OTM#ryHt3dpS?MrSӔ9Hp)6۴ryQ,t 䡉2gO?cRZOOɱ 5dCiIP7"%iK:~(,!/H k#3S(tx9t̓~gw+^|$ 5m H A(]9  ~bt` JRݖw!b6Gg_HqBMh߆7IA#$7N\QGdu'åflR 'V}] 3Rm>&xĉsv6hg.栅h#.ʨņii)V)u kBjӕF8i>7kdZ>\ ,,rylƀ,^mféY--*+n&ZUu{k q;1/\:N]k(׿m TKqt1XeP(7Z˱ a<lrJzź0(g҅8చmrKsd|sQ{sH+ So[q9I蚨dg5!M6P/tz7$2`GgW7Fk%>ʎG>}饥:w> P%]ڇMI'5L{؅U;T^СP{*^.&2I2bjS. XymwO>5?x ;/)tׁo㓟6Pڃo٫ ;!~?h+af*'3no2L Yh*oAP6 UO:CH'tT#-s4+N&l4gQ•e1qhܜٸq$4-2ы ̣0ɑ=lO!f:,cG[U<"7EbCxԘtJP"r&I!c T͜jlrzJY.G´_ 1ìׄYdQ&hvnilfpn%2ωtsl;xs= {s?ۙ t-AWS3 ]&7 Q3-D+5Q%h _c,M R^1H^L?"LVc iHdYC@e '1\T^d#GXhHM$#yH@TnP[9`Nƥ KUZ0Ce=jLjWB3b9yNrՓ(lZjAZ78UW5TJvEBZUγl(A"جER!|eBVO 3R^1xq*\]s}JӭnkB7ڕnqwk7]/{7(}י0_׸Aq٭|a N [92^3?.ĥ-hxbplIIq}V lH@э% xِkİ.K1Zk Ϊl< Y(&A>@w\pa%\:en(gs\6ֱlt:(DgqG>͝㖎yKNRC~fc$Ct ,IZ\,F{+7)|^gľF#Jp]>ĶalLtoi蹎w 'VSy1ξNk7[gg )uj3T~ي6S/sz[XcSsv _jgLvB zqfn7[/h{YimxZނ3Yo?+;Ϋ6Go\O֩?2`?U?~6eQ3{t\:gKW8[׀|rR3Rrҁ_zkqq"X~l GK81@#|$5z>(3/X{WJoCȃ$烛biFbOx8~';oQĄ)h9W}1@h~uwjNa0sGHvړ'}xN$9s:syƦjBy{vByX8cu_Xm8*4c"JSh=DGqHٗ8wX(3{z9}g)(2H;xlH~8~ahh(􌹷X\nĨ9X{WV؉TXHVoXDs7xs( DqxNNe`- uYNIdM Đ )MHiPɑ4 !) #i'+M1yU^#'e_J0XRp6Vy-0ղ|0TP7YX(A.S`V9+iM []YW*aT'@Q^ieZXe3;UX^XiXcjz9 +tVBYeZc [Xw4|X1|<9)XlQyyb~VuxY YW73d k$Rs>L%SQUyZ ]aiMŔْR}f4]ڹ ՂɝSoH\_):" )N/eT T98_WɟXsJd9Ġ9pP3cD^q詠 7!jV"JE&@ԠU\.ڎ9M6 ߕwʄxr=i[XqWxu^ |q]Uf4')tnu ;ˎN ۷yC2úKtx~x[ Zm0{|yꛎ\|wIAJB\xhh,óF hbH[싴j_e~hۛC݋d \B8TKj6[L(2hD^,3 ȗ[LJ[ .)U F;L|ͺ1̬;lה<8 HܑiƯh8 |Bhσ {l5ͥQ >>???CgC66D44C;;D<<\==u66DUXfw.D.DDUUXX9DBffwwDDDHHHJJJKKKPLLSLLVOOPPPVSSUUUXQQXXX[[[]ZZ`HH`\\c\\DfDPwPVfc```fffhhhmkkmmmrlldwspppqppvvvwww  '..''  ??..<<>>N ~__ll}}__NN^^nn~~2!}}C̍сș̦!, Hi(3ȰÇ#JHŋ3jȱ-1 rP3@:\ɲ˗0cR$ڴ;&H2USϟ@ j@%ʴӧP'.u5ek!I 13v5_HBUkRk~Jݻ& X5kዚ26Õ>òĮ]vځ] ZⰘc˞qz}&Uo̽ m˄ y؍9i{v%b.ugnv*I?*DU$e=BS| 6F(gUhfv.8!$h(j("Eb0(4h8cV@)DأE?L*yLI6)T$.\vY.^ ӏZzihE?)Jm/͉dt։{ɒzWk'k$zD"$X6h}B)XzDڧ2kj(=zjDB'U-*d'p+D&(g똙k,6,:cH,d/ E;дV{mW֭ր됝x,\i*n𪅮@2d B򻬞,BܯAvv<lp)M@IfE`/[œH T 7 2fb(CjZcl{WNˊB;p[[\-fÙdۘz}vk[wnmt-jrύ~8څSD!|6>ge[.vW)y .Ž:1误.~ή;Ȅ(a/o'|:n{ܾWogwO N觯E<㞐 ?+#>Tt '7Ӆ#?7?Odg ..Z Z H*A }xPȂ HpQG8~{2\2axE+7 r:(rDP;DZA  @O(x$DF78\ؾU`_"H2Fq2 3f#):j2"#ԧ5,S`X," :P*g2҆5򯞐*%k@8nOreݔ K](*RQT(0E z`[20czD*yM > t< Nf:wع'%+*KLCyTҜDv=> (H|I?;$< )$䣨"$VQSdNE 甩< ` 6!ϓrV1Ag44TCj:.|EZq(@: Jِp=N')pRԫ_ R'R*Qf7{rLEWTt|i>Rn~5!l.hLSIخB5aXG S%V4u=_+` p+Zgf%(wRָ`r_Kوbw_ 5d>Pq9 $h83*}_, C\AI؂DK0.I@NVD&ڀ&Ű*KkE*XbsXQxńa"Sob/n jL:Ϲy&$ܺyπg뾻%Zv气E|]UwBpӜ-9. W]25Q6WN5'=/[Wak_7jPv3MCNիuq-c:ɮlnztmх_tRS(68`Hmg/H,I5P2@0 8hU sQS`-PSP `aaQ!67 Z̀Iy17d /$0:C)66q (P@R1Hp@clu_A"! & F dsYAk /Q/b&Z" sz>ٯBDmЧm?&آҬc"Z۱ ihY"(k! Y9Ph8O(6kb278K_;8;)"6A{HG*?7G熭vTr'lq>16;,bS`PK֒-iہ>3.b.u  b XY/@0ۦ0P1K&Y+s-U;2k2;336SL@l.TI9?H2Zh>jlToL@dLZLLYjv+lK} ?J$Kb!\*HLTUUOtaYHGD>?Mޔ>Nc&1{PhʊLRAR+eX”|t\(>PQ Q Z PN p|U@̽5uS %#UTXWU[Xu J܁>VݴZ|WK i\g^Q^ y  7=.2ͯ@]u]Z۵_3,AN5 F af6 Ŕmƀ q=b>u>B-`dMOA6c:VRt$G.c%^|qٚ"Fb&E(*f-ĔhVeeSt-AJdT=3%Aٛ} νx ~= < rNL,c9<#\>$~:5n1 0r '.q#V;껾nP;@ގf½2-2~Q 9nLJB]rWkn Q MOP Q 1'KKN H`QCC1"Ymmp`'[΁>OM  @p@ C.l 9^0= "r \@a mľo֍.#P.^rg^(D>y Xn 3Gd׊f Нhw8֎3 v.}duSt!ҁq(%{')ρv j;~W6*@πJӞg@Ht9;ZN7P4'KYy[^||b/sd iM'8Xw18V}=X1I{/rkOm,Iw?#TT;y?Xe4/Y-Ore_W&Oo$#[J 6MЯuF*zX u-8gψ4H.!M@B Tذᢅ4I|PF3BRH%MDRe-;fQL0%NF#B]}TP5tّ5ꜙqU^ŚUV]x(THǖ mݾW\uЦҊE0#B… FXbƈc}^_ƜY3Ȃ3\rgɃ7F5ʕɶvm:lڎ_~놶\pōG^i®;tխ_nv5Sݣ5nɗG~2~=7W_~ǟ~n/C@vC @'\@D{6CCODD{6_ʓ-Fo|q-ñGQѾ$1Y\Hd߲OI'rC(7ڑB-K/9K1$L43M5TM6߄3NݔUN;tN.j׀ .s[oR{FoL򱽻˛? _۫7-Z?~BWz'8!%<aNHa^anȡ^}]A\f!@2Hc6WFn*6ލJ.dpbT%N~ f"R"j]ZiN(fvI&nYjƥo'ht9* 5ygboty[-0IH'>X**iMR0 ec '*u|h6ůjKŠdvΙjF*^%PV败mcTˮRɪ'o N`/3o|Wku KTſLqoq)9U (X0mW$?Wz}.43=',3BLt"UV_-qN:m

4~/Ka y^J.㎋*ᆎ90IC.?x~;좓^R>^󾃀T|K{񋮮;˃<5~ONe^݋U3~~c~vbOPc` wk`ՑiLO( ^%4!NPBЅ]Y@pm1$ >=kA MYGZ -hOlSE Mq 6 YEqJb|(5 BKka0Q~`<ԁo{cr QX^ˏreH.#ֽ[},$%C)gd: E<_oά, iZ҄*'/{Qp[H3T)FLR3_ޗ6A_lJ){5\(?jԛPzKؔ2a. 14-o NT1wƈ-nAQ7XW};|@ޣF(`Y`JEF'1RrߪZ! ^b%͸@gd$ӕOZ>VgJW[޶m.Z-i}H5y+y b9Dv '$~OȄ$0OVNCՉ&߬An~|,ɼ.D*J-oG[|o _9Iz݀BY4#߮t-GWv,Gn?h ǵ0z}QNqto6ta{F*ss;.wgw*-pW|`Ѿ>܎?w0 Fl㧌[پ\|tyAyWa;]C}BCB\=O|F:??IKί|!u<:&wz7SW~ f)USU%6Su@X,A[X7UHb>UZPUYYXWX#ϘXW\ Z}٤PcYZYvȐVY]I4UgHUZ匠ōI% gl8iHEiGɓ0hO/e0@iaaNYP X #F~]^)` ^u#mA+Q"{gBjv+/"a$'6va{9 MoY6%6_bK#e 6hNzƘ?2iҕ`h'a^ْ7a3_ɓ֎tvqG`o™z&qK)絚Vd|y]`g~pNIyUjQW(Be rWkEC7 #Sٓm9vUÝs؞ 9=V&T;7tyylY# {fK)mdö h)ʡ*$&  #'ڢ):+:,"plA'Z\֕<*3;j^9jy67L 246%:5WN*\:9ޔzU(o zEiɖiJv4UڤrVYz[J]T y }9nt@li`]jdɨmJhojN󧂪vsuڤ2ag3eykP`V&qj ]گ{ʯ0 !k 2 K'nYmZ:+ʱa ۳%`\*ˉsz619b8미Q0W+Y& W+QWG[SaV0)d<˵lKn52/'sd[d}5m۷oq۵Z{9DxKzukK; ;[K3f8Kk{ uKĹ1K~oA :XT[ATqXe2"kP#5+Y. H̨F˲(obcRzVV( ÉM֘뛼7uFV~KS4+KtpȴO2Kz;z[Gĺg۹lk[M#׿FK 4);+,ʿk8w+#ƀM,Nܱ8נI<և'ޛ6.U  ךWPܧfzJk]ԯ~_zR{گTk'՚rtU4o~Һ|=ǐ ǎJkܟ2l3K@w C++ Annotations Version 12.0.0 en-us EA989A949A Frank B. BrokkenThe University of Groningen9036704707Computing, InternetDec 25, 2021 annotations.gif c++-annotations-12.5.0/html/modaye0000644000175000017500000000010514466730207015640 0ustar frankfrank c++-annotations-12.5.0/html/functiontemplates/0000755000175000017500000000000014466730207020207 5ustar frankfrankc++-annotations-12.5.0/html/functiontemplates/selection.gif0000644000175000017500000004337614466730207022700 0ustar frankfrankGIF89a|    "" "2   """ #'#(/3"!3'&(+0+-1.05.38/5?222333346888;>_16T86_?=g*)!C)Tp+D"2D,-S)6D22F92E<*]2%m$1d #z#9u&aIreat65:@9P몾y <%X;V]%EZ.X.k .k 1YB:+z>jk@Ǻb@Kb1Z^+9dɻ<-Y @^H=VEiP|J5c24jżp @ؗ ģLlba|bq,T'(qn Hͫ3c~{6s`W<\CJiaִ BVJ4@?[C9!iKk%ҖkZp"͋ipM@uW ̍p,Rht%T{v)$Ưr#KͪIlrlRHesI#ȦF8R0? ߇>+]  yMff`2H3JWej1קʇ%uвe]NT3ZJ?(OՒէ1]:әLIWv]%[ ъnc2=8N :a/hܱɘɦYTB3LeF(qθBoJ,jd:wqHjrT| (U(eqhDә-4¨ ѣgaf.$[DprB(KgNaifRjL)l MIg=!YNuXERR[ES'=7ѧ~4j5@UzS?I <ҵ-lI!:**iiB3S#V;ƨU#VE*Ɩg-kCIы~MIwacבW`ȥ P$8c6ʱ=BA bjwZyC-˕ERSUnqWJt!ja 5VUYsk\@+UB BL*l1@8Wvbx >R- xKb 6UaKW*p x \JZӕ#) 4] 'l͵sov$EW,aOl4l9C]@6TTdOvD6rVܖ_mZxVzgb]`p[ dq a6gh@;.K bH6>48̞nKuo7ѯx3b8L^\WIXRgT9v˨cd;o]vT}brǢfk[ʱkh~v_t;{\Ab{xwKڍ|s0Z#l Zf g% ko*Yq@|c! +t%/9zN>\f"W>q|aL\rs8Kr'}*D.} š硓F_3Y2wL.+ao&\dMb'ozޒEr|)M&kFL@~Ao(ٻ$nO;H+=GS!zЉk%K_uÄmaYk\ywޘGPDyʑHL]d^%0fqx/4/arW}{λV#y/^1tsÖ΋mx˩G+GCU\"5e:59N}H0$<!& 9 MG}f}"}3ga{Vq/"<#ģ& 4,?5)&F;i'm' TJ4>a;FU5Q,&om7%5TxC<u%cS2T#!e6hA>G'z$XgBYX= ?T5ZcDU6"7b@?xI'g_XEτ?bM5N8EuA0؉X8 PSn5GĒ.PM.ƔA^S$iԊU548!_wx@ 8XxpTX\|r8xKE؎艝(Cuu؈B%Ex|gJ2PY]T`\YUOTqO ֑ AąJeh3Nm&$ D{ҋ+}bY/IHVX@"YF JQ0I`L %]YLdVX@qL4VSO26*Hx~6YSa’@9/1"9Ӹ xQ@QiHŨJKbFX1z" -`EpF[TEd7Cd/I3C(rcpabYe7}qmuuW5TRișƩ(8cb'03cwcbӁIJkakpb!6RHd$ NcteZZ[a3eeX!$)5f>X E4Y7aiiV\ J!Ra!EVk&h6Xla.2i3[R&2Pz!0r/;]-j#z"0;祆rȑv¥gJ&pzqfʐ¦5vs,uzuQ~)q_0ZI:cC5.b~[ q:aѩ)R, \ǪzrA21Q̚j~nZ71Z=YΚz9VUJn꫙Z2҃U;)ʮrٚixe*٥:cqƷc:ʬ[1v @I:pQ@V-"Ȍ*ڱ)$-0K>qs3𮷡2#2l6myJ7&% F SXB[e8,)B{Xvٷ.p8sKg'Y041'K(iG2 GH4Uسh2=sUz(kʪ=K"%NsH4_4iT"cCbzR!%c3@5A3lJ{)dU!&ZTdG!b1,µR_W&gmrQRZ] /oI#+W$;B2bC*r!G###Lbr/u!#/γ}pZw- R`O+)SUW*&ho0XR` C<@BDt3UͿa*f/CP6!u3O5bDՌ"? Zjx\aSB(>F U/R ]DGɺJiX\}do6eYqZΥ *g?Nݧ#颸uր:-!a,`kdi&cI 7V?*aBZaݙ} q&pqHN*P/KSΣA3itY>^^_Bd: dRFmn^p%{RU~Mmyn]~v>Vw1^芞v)1^ꦮ hsꮎ޿We뺾R>^~Ž =0^~؞ھ^~^T=T;~)ߨ_? ?_s " ?&(%,.+2?4o1_8:;>B?Do_HCJN/LR?4TXoV\^b`?f^hljpr_v?tz@~֘ 9G{}_?` _h_08OoCP oUoH@ȟ ˿uR֨?osCP!z_G?LQO5yo1@ DPB >QD-^ĘQF=~RH,RJ-]SL5USN=}TGCETRMiuUTU^ V]~TkXe͞EXmݾ([uśW#]}o`… :bƍTXdʕ)FYɘ9ZgѥM.Kj֭v[읡PƝ[MR"\pōG\r͝?=ҭ_Ǟ]vV ^x͟G^!>_Dp_~0@$@D0A'b%0B '9 e%vC?1DG$DOD1EWdq'2 gFođOTi2H!|Q!D2I%C,2%2w4RJ+&S1K/TrˏdL33dE1IM9dFȤ3,j|)B jZGt1wu4=MKpX T:cZ6bGֳv-d[^ԴnZ!& G>'lަ"*7 &"x`Cp7 WC<( N%y#q#@ǒmtn˺!DW!,$fOHU: V]\Jt؈./bhypIϏ~oG 7ZT/w9kۇڙMtCDLrJ@tizdQ1" :bc %)f16(-1@eP('1Q1l ~@,2b\? @Ù12j? T kR$[!:; ^{BiP0  )*"% oɚ»Z3BêbPhA% 5i*9 aPpK0C*/D0tџB= 5d"gU(C0* {A?>)A?fɉ+!ѦJX1QB,@cQ)n*y(!sɟF1? t_tˮ5|* /΢ٻҹD},y$r-.J&Qi#<B<>J,/A-~0K yB#jQ҅O(+=RI4I~ rGƅDC" ѯ?0"31E9DJSC;<}G 1\dH,J(̣,I;\(Fcbǡأ$9 =&R9ɼ"(૬µLD³tѴ7z!tʊiKI KHC˗4KjͬKY"˶̕:MNd)k@ɖ?1@*EjlOHN4%wyrOLjJO, !_LqLdy%eA&qI쒢Ъ޼6N -N۱޽|؄x]sOc=W[ֻ-3q?1,DXS5Q_9=/iP-m2 ?)VmT0>ZYu! f Qkጡʋa ~a` លaWaCk !B#6n"Vb_'$vV,>=+6\'bb,c3UcI)6n5@5];<=>?@A6CFDc(cuGHIJKILNd(bO&R6SFTV"% bP)Z[\]^_[N/X`6cV.)@fvge=ic}Xލ3PmNE XgP3s q r sfgP0y w x yg{gg灶WUP(8hH臦 Uhhƈh/~ 6i0(閎v i2vn Hu.j > e 9jXhjxg.ejj_S@(>vnhFl8/xkÐ릠wk0in}~lV좮ll63^bXE@.fmj|.[@EX>F[(e ^ ؎h;ھގZ(c8 V .nkPfnn N f(b@FX?hE@gF .oPlPo՞X6i> xiaЋn'j7 _XoYIp /bm  p8jWm6S R Su,`o~Z7 Y ZuDJ(pfGb _/`hvgOn knp_g׉hsq"vFP` ww"/b@hzo7r~7rnt{|O7s2OTwx@A/gx'xs8ޞ픏oUyByPkyxxXV^?sz(z^gkz_hzxz v zpr_v {0{@{kv  {o t}rG|{{`"rhF_o |/j|}}E~G>?t?t{_LjxI}=i~}y7! -؂'7GWgwȉzPG*pd710R,h „ 2l!Ĉ'R(ƌ7r#Ȑ"=S4enŊh^?P¹`r%;l&wrl7+Iş (NK7 {Ϯ">f>Tp%=^Np|;  ;@'LOes=UŠ`P$  \]x{ U E|NX?ʬGt'8`|r&Ewoaԅ@@!a@ ɦI `C.tA2ls]&ACN&؉bߠ@DۅE980PvtQ `Qu$(&F06M8^O =wJ.s‰͢=OT.2GhΜLl"'L\hڜBteAO!R%Fюr4diE}ȓb(Y)Ks4 :#S| " FD5*T-ӟWKuMԨr5bSI?*f]=+þeI!knֹ̊'u}ju ֈW6|դ h\w}uR29. JLh{Է( l},ênTkE{E=jOsMGNi[V=5aX\ز~psⶩ/'>@ g*!JA|\8KBD gi NsNh?~c`s f7JYqK*W~c. )|D_,3 D!ŰχU8SgA ȃ.{3Əu]4[RENL*y!tmb- *?+E&ȦE:q![m~CJ=^ٱY,}Xf[监 ;mWp|2Y4&¡as:ZYtƣbwG+ SJh.vz̄Yh@Ӓ>.[gZz]I=7 fEmSδHlMK0veJO~||.Y&nsȴ'QCd=b$nԝ.ضc+Kэ kMn S.^Zwx>r8y|\_1^lx>N[ 2+[%¬lsqkAWB^?IG#ݶ/q:RIdZf񡝞h랡c.[Ѹ~Hƹ@aܯNѵs}{/xzه 7OLyL.'Q/Eǭ; r-?2@̷'ԋYpy2ԡOԢ?Gӯ~ZЂB8@39h s@.Q,בuB@ @!pH8^A2 'tB/0OB I_5Kr#B22B8 8@\ -p#` '`Y*d ~ߗU~ *!!!0'؂1̅2Ba[m!Q\ z_!F/A6I`ɡQ__m*:IOan&uB>`iIi&'F ~џ_  ta 0BHU/n/.0>a/``.6j z߈dCVE@+Rd,c@$j_%2GDD02,F ))J.3FD#M#Ԣ ⟃ODH68=&1>`H7$#F%M]Fj Rn "(V:?cMdE&[FV>ڇٌ4%S\~I^BNb[GF4ڤ"rG)_P6f5>$JNJ~፥<%9r%_fTn_U^RbefV֣9H-"s`kY#Z%m#;UeEep.Wf# fEbsE:gc60dv] FbR!(PRy:Fa.ixdxigh@)Nfd4#Peg%!!k\&2>6ycfmnq_p;tg:c<F\gufD}`wEInDzeZghF&hY!h~n_(Qd)钂J_%ncST VH@j>ņޗimΟ BNha|V֩)dtA)@*&.*@yVV^*fn*v~**B <*\Hj*ƪf'Ϊ**S ++&.+6+@ 8N+V+檯n+v^*. H+++ƫ+JIN+Rk,,f>,Z*&^,fl.,jkvXȺǦ,N,QTƾ,Ƭ̚+iê.T),f*ά-kk,,ö4-Omn-v+ެV^u+B*X@Վ:zޭ.m-Jm, + ,(Zͦ m)@Ԓl-ކ^6R*涮@*PjԪ@릂@FB)L*tR*Dݎ.Fnp,.v/v..+(/+$*6oO=r_o˲ 4@s Z7 7yZH`x#/̺?¶G s3W:9Bo5{Jŋ>اn}<.>;lgmKJ,Kv36n_b{/ .@(a5p,9X2@%Z"cGA鱄3'QT I/aƔ7qԹ'LH lgћ4U)OF:jUWfպkוUތ;lYcbQ};WlI*]eA#pKH,ذAA/hPI}30 &@$}Wy_@+ 6p0Y0a{Q8fྉ#ALJޕ>zuױOK{wDo7oz^`a/Llk @Fod $^/' %˯"!NB`!HVp 9IO.iq4i;x1$7h J @.b:a d 9BIl+1,wK L`De/L{M,J TAݑC{l"%Hh&' 7@)!s͗2ud`NI6TLP%q=ܓ)_I-XcRԄCg)SVs$#TLU:qVUYڗ$ &]y3w፷a{)nnc MM]4wԘY V\>a"DlbxA^|I.dVn_s9%iˮrS͚xfHX]Cn駯䩩F4V\-雘Vy`AjsŘ@C݄mOdAE]Ojn*ksmKs@7$3 0t E#/tgKQg1tX뱗ǹᆴJ _/8u{eg_ʭoi> q7- A e%1A nAB%4M@)vq a@N5 =D!P:MtRLUE-n]F1 јF50 ;c++-annotations-12.5.0/icmake/0000755000175000017500000000000014624637064014733 5ustar frankfrankc++-annotations-12.5.0/icmake/examples0000644000175000017500000000341314466730207016472 0ustar frankfrankvoid tryCompile(string source) { string obj; obj = change_ext(source, "o"); if (obj newer source) return; if (strfind("koenig4.cc" "personconstr.cc" "stringsmove.cc" "binarystring.cc" "stringconversionerror.cc" "binaryambigu.cc" "binary1.cc" "virtconsorg.cc" "refwrap.cc" "ambiguous2.cc" "ambiguous.cc" "buffer.cc" "perfect.cc" "basename1.cc" , source) != -1) return; system("g++ --std=c++0x -c " + source); } void compile(string dir) { list sources; int idx; chdir(dir); printf(dir, "\n"); sources = makelist("*.cc"); for (idx = listlen(sources); idx--; ) tryCompile(sources[idx]); } void examples() { list dirs; int idx; string cwd; cwd = chdir("yo"); dirs = strtok( "intro/examples:first/examples:namespaces/examples:" "string/examples:iostreams/examples:iostreams/cc:" "classes/examples:memory/examples:exceptions/examples:" "overloading/examples:containers/examples:" "containers/queue:containers/set:inheritance/examples:" "polymorphism/examples:pointermembers/examples:nested/examples:" "stl/examples:generic/examples:functiontemplates/examples:" "classtemplates/examples:advancedtemplates/examples:" "concrete/examples:concrete/examples/monitor" , ":"); for (idx = listlen(dirs); idx--; ) { compile(dirs[idx]); chdir(cwd); } system(P_NOCHECK, "find ./ -type f -name *.o -delete"); exit(0); } c++-annotations-12.5.0/icmake/pre0000644000175000017500000000051014466730207015435 0ustar frankfrankvoid pre() { string files; programs(0); files = stringlist("", "yo", "*.yo"); cleanup("paren", files); files = stringlist("", "yo", "*.cc") + stringlist("", "yo", "*.h") + stringlist("", "yo", "*.ih"); cleanup("tab", files); cleanup("trim", files); exit(0); } c++-annotations-12.5.0/icmake/programs0000644000175000017500000000270314624637064016512 0ustar frankfrankvoid programs(int docs) { if ("VERSION" newer "yo/version.yo") { printf("updating yo/version.yo to version " VERSION " and years " YEARS "\n"); system(P_NOCHECK, "rm -f yo/version.yo"); fprintf("yo/version.yo", "SUBST(DOCVERSION)(", VERSION, ")\n" "SUBST(YEARS)(", YEARS, ")\n"); } md("tmp/bin"); if (docs) { if (!exists("tmp/bin/htmlindex")) { chdir("src/htmlindex"); run("./build"); chdir("../../"); } if (!exists("tmp/bin/rmindexlines")) run(GPP " " CPPOPT " -o tmp/bin/rmindexlines src/rmindexlines/rmindexlines.cc -s"); // only used in 2024 if (!exists("tmp/bin/celeb")) run(GPP " " CPPOPT " -o tmp/bin/celeb src/celeb.cc -s"); return; } if (!exists("tmp/bin/paren")) run(GPP " " CPPOPT " -o tmp/bin/paren src/paren/paren.cc -L" LPATH " -l" BOBCAT " -s"); if (!exists("tmp/bin/trim")) run(GPP " " CPPOPT " -o tmp/bin/trim src/trim/trim.cc -s"); if (!exists("tmp/bin/verbnrs")) run(GPP " " CPPOPT " -o tmp/bin/verbnrs src/verbnrs.cc -s"); if (!exists("tmp/bin/tab")) { chdir("src/tab"); run(GCC " " COPT " -o ../../tmp/bin/tab *.c -lfl -s"); chdir("../../"); } } c++-annotations-12.5.0/icmake/latex0000644000175000017500000000043214466730207015767 0ustar frankfrankvoid latex() { md("tmp/docs/latex"); system("rm -f tmp/cplusplus*-stamp tmp/_cplusplus*-stamp tmp/dvi*-stamp " "tmp/docs/latex/cplusplus*"); latexdoc("", 0); latexdoc("us", 0); printf("the log files are in tmp/docs/latex\n"); exit(0); } c++-annotations-12.5.0/icmake/logzipr0000644000175000017500000000071614466730207016345 0ustar frankfrank// names may be a series of files or directories in src that are zipped into // dest/zip. dest/zip is logged. // src and dest do not have to end in / void logZip_r(string src, string names, string zip, string dest) { list files; int idx; string file; chdir(g_cwd); dest += "/"; md(dest); if (src != "") chdir(src); backtick("zip -r " + g_cwd + dest + zip + " " + names); chdir(g_cwd + dest); log(zip); } c++-annotations-12.5.0/icmake/findall0000644000175000017500000000107414466730207016266 0ustar frankfrank// assuming we're in g_cwd, all entries of type 'type' matching source/pattern // are returned w/o final \n list findAll(string type, string source, string pattern) { string cmd; list entries; list ret; int idx; chdir(source); cmd = "find ./ -mindepth 1 -maxdepth 1 -type " + type; if (pattern != "") pattern = "-name '" + pattern + "'"; entries = backtick(cmd + " " + pattern + " -printf \"%f\\n\""); for (idx = listlen(entries); idx--; ) ret += (list)cutEoln(entries[idx]); chdir(g_cwd); return ret; } c++-annotations-12.5.0/icmake/readlog0000644000175000017500000000023214466730207016265 0ustar frankfrankvoid readlog() { list line; while (line = fgets(g_logPath, line)) g_log += strtok(line[0], "\n"); // add logfile entries w/o \n } c++-annotations-12.5.0/icmake/log0000644000175000017500000000014214466730207015431 0ustar frankfrankvoid log(string file) { g_log += (list)(g_logMark + " file " + md5sum(file) + " " + file); } c++-annotations-12.5.0/icmake/man0000644000175000017500000000061414466730207015427 0ustar frankfrankvoid man() { md("tmp/man tmp/manhtml"); if ("man/c++-annotations.yo" younger "tmp/man/c++-annotations.7") { chdir("man"); system("yodl2man -o ../tmp/man/c++-annotations.7 c++-annotations"); system("yodl2html -o ../tmp/manhtml/c++-annotations-man.html " "c++-annotations"); chdir(g_cwd); } } c++-annotations-12.5.0/icmake/writelog0000644000175000017500000000034114466730207016505 0ustar frankfrankvoid writeLog() { int idx; if (g_logPath != "") // do not store uninstall info { for (idx = listlen(g_log); idx--; ) fprintf(g_logPath, g_log[idx], "\n"); } exit(0); } c++-annotations-12.5.0/icmake/verify0000644000175000017500000000057114466730207016162 0ustar frankfrankvoid verifyrun(string file) { printf("\n" "checking tmp/docs/latex/" + file + ":\n"); system(P_NOCHECK, "grep -i \"overfull\\|undefined\" " + file + " | " "fgrep -v polymorphism/undefined"); } void verify() { chdir("tmp/docs/latex"); verifyrun("cplusplus.log"); verifyrun("cplusplusus.log"); exit(0); } c++-annotations-12.5.0/icmake/mark0000644000175000017500000000012214466730207015600 0ustar frankfrankvoid mark() { g_logMark = backtick("printf '%3d' " + (string)g_lognr++)[0]; } c++-annotations-12.5.0/icmake/clean0000644000175000017500000000054614466730207015742 0ustar frankfrankstring remove1; string remove2; void setRemovals() { remove1 = "tmp ../sf/index.html ../sf/cppannotations"; remove2 = "o indexentry/o aux/o"; } void clean(int stop) { setRemovals(); run("rm -rf " + remove1); chdir("src/htmlindex"); run("rm -rf " + remove2); if (stop) exit(0); else chdir("../../"); } c++-annotations-12.5.0/icmake/uninstall0000644000175000017500000000144014466730207016663 0ustar frankfrankvoid uninstall() { string key; int idx; int nDirs; list entry; list dirs; string dir; if (g_logPath == "") // do not store uninstall info { printf(LOGENV " environment variable not available\n"); exit(0); } readlog(); for (idx = listlen(g_log); idx--; ) { entry = strtok(g_log[idx], " "); if (entry[1] == "dir") { dir = entry[2]; dirs += (list)dir; chdir(dir); } else if (entry[1] == "file") remove(entry); else if (entry[1] == "link") run("rm " + entry[2]); } for (idx = 0, nDirs = listlen(dirs); idx != nDirs; ++idx) removeDir(dirs[idx]); run("rm " + g_logPath); exit(0); } c++-annotations-12.5.0/icmake/cuteoln0000644000175000017500000000023314466730207016322 0ustar frankfrankstring cutEoln(string text) { int len; len = strlen(text) - 1; if (text[len] == "\n") text = substr(text, 0, len); return text; } c++-annotations-12.5.0/icmake/run0000644000175000017500000000015114466730207015454 0ustar frankfrankvoid run(string cmd) { if (g_echo == OFF) cmd += "> /dev/null 2>&1"; system(0, cmd); } c++-annotations-12.5.0/icmake/zips0000644000175000017500000000237514466730207015647 0ustar frankfrankvoid zip(string dst, string src) { system("zip -r cppannotations/zips/" + dst + " cppannotations/" + src); } void zips() { system("mkdir -p tmp/docs/zips"); system("rm -f tmp/docs/zips/*"); system("ln -sf tmp/docs cppannotations"); system("cp README single/legal.shtml cppannotations/txt"); zip("cplusplus.txt.zip", "txt/*"); system("cp README single/legal.shtml cppannotations/latex"); zip("cplusplus.ps.zip", "latex/*.ps"); zip("cplusplus.ps.zip", "latex/legal.shtml"); zip("cplusplus.ps.zip", "latex/README"); zip("cplusplus.pdf.zip", "latex/*.pdf"); zip("cplusplus.pdf.zip", "latex/legal.shtml"); zip("cplusplus.pdf.zip", "latex/README"); system("ln -s ../../../contrib tmp/docs/html/contrib"); system("cp README cppannotations/html"); zip("cplusplus.html.zip", "html/* -x *.svn*"); system("rm tmp/docs/html/contrib"); system("ln -sf ../../yo tmp/docs/yo"); system("ln -sf ../contrib yo/contrib"); system("cp single/legal.shtml changelog README yo"); zip("cplusplus.yo.zip", "yo/* -x *.svn*"); system("rm yo/contrib yo/legal.shtml yo/changelog yo/README"); system("rm tmp/docs/yo "); system("rm cppannotations"); exit(0); } c++-annotations-12.5.0/icmake/removedir0000644000175000017500000000137114466730207016651 0ustar frankfrankvoid removeDir(string dir) { list parts; int idx; int dirIdx; list entries; int warn = 1; if (!exists(dir)) // directory was already removed return; parts = findAll("d", dir, ""); // if there are still subdirs if (listlen(parts) != 0) // then remove at some later stage return; chdir(dir); parts = strtok(dir, "/"); for (idx = listlen(parts); idx--; ) { entries = backtick("ls -A"); if (listlen(entries) != 0) { if (warn) printf("not removing non-empty dir ", dir, "\n"); return; } warn = 0; chdir(".."); run("rmdir " + parts[idx]); } } c++-annotations-12.5.0/icmake/md0000644000175000017500000000153114466730207015253 0ustar frankfrank// md: target should be a series of blank-delimited directories to be created // If an element is a whildcard, the directory will always be created, // using mkdir -p. // // uses: run() // if the target directory does not exist it is created and its realpath is // logged. string g_lastLogged; void md(string target) { int idx; list paths; string dir; if (!exists(target)) run("mkdir -p " + target); else if (((int)stat(target)[0] & S_IFDIR) == 0) { printf(target + " exists, but is not a directory\n"); exit(1); } if (g_installing) { target = cutEoln(backtick("realpath " + target)[0]); if (target != g_lastLogged) { g_lastLogged = target; mark(); g_log += (list)(g_logMark + " dir " + target); } } } c++-annotations-12.5.0/icmake/gitlab0000644000175000017500000000027014466730207016114 0ustar frankfrankvoid gitlab() { run("cp -r yo/version.yo tmp/manhtml/c++-annotations-man.html " "tmp/docs/zips ../../wip"); run("cp changelog ../../wip/changelog.txt"); exit(0); } c++-annotations-12.5.0/icmake/remove0000644000175000017500000000042014466730207016144 0ustar frankfrankvoid remove(list entry) { int equal; string file; file = entry[3]; if (!exists(file)) return; equal = md5sum(file) == entry[2]; if (equal) run("rm " + file); else printf("not removing modified file ", file, "\n"); } c++-annotations-12.5.0/icmake/backtick0000644000175000017500000000016014466730207016423 0ustar frankfranklist backtick(string arg) { list ret; echo(OFF); ret = `arg`; echo(g_echo); return ret; } c++-annotations-12.5.0/icmake/md5sum0000644000175000017500000000015214466730207016063 0ustar frankfrankstring md5sum(string file) { return substr(strtok(backtick("md5sum " + file)[0], " \t")[0], 0, 5); } c++-annotations-12.5.0/icmake/install0000644000175000017500000000221714466730207016323 0ustar frankfrankvoid install(string base) { g_installing = 1; #ifdef DOC logZip("", "README README.papersize COPYING README.legalese changelog", base + DOC); logZip("tmp/docs/txt", "cplusplus.txt", base + DOC); logZip_r("tmp/docs", "html", "cplusplus.html.zip", base + DOC); logZip_r("tmp/docs/latex", "cplusplus*.ps", "cplusplus.ps.zip", base + DOC); logZip_r("tmp/docs/latex", "cplusplus*.pdf", "cplusplus.pdf.zip", base + DOC); logZip_r("tmp/docs/latex", "* -x cplusplus*.pdf -x cplusplus*ps", "cplusplus.latex.zip", base + DOC); #ifdef MAN logZip("tmp/manhtml", "c++-annotations-man.html", base + DOC); #endif logInstall("contributions", "*.zip", base + DOC "/contrib"); logZip("contributions", "GGD.algorithm " "chist.html chist.pdf chist.ps " "java_cpp_keywords.html", base + DOC "/contrib"); #endif #ifdef MAN logZip("tmp/man", "c++-annotations.7", base + MAN "/man7"); #endif printf("\n Installation completed\n"); writeLog(); } c++-annotations-12.5.0/icmake/loglink0000644000175000017500000000012114466730207016304 0ustar frankfrankvoid logLink(string file) { g_log += (list)(g_logMark + " link " + file); } c++-annotations-12.5.0/icmake/loginstall0000644000175000017500000000155514466730207017031 0ustar frankfrank// source and dest, absolute or reachable from g_cwd, should exist. // files and links in source matching dest (if empty: all) are copied to dest // and are logged in g_log // Before they are logged, dest is created void logInstall(string src, string pattern, string dest) { list entries; int idx; chdir(g_cwd); md(dest); src += "/"; dest += "/"; entries = findAll("f", src, pattern); for (idx = listlen(entries); idx--; ) run("cp " + src + entries[idx] + " " + dest); chdir(dest); for (idx = listlen(entries); idx--; ) log(entries[idx]); chdir(g_cwd); entries = findAll("l", src, pattern); for (idx = listlen(entries); idx--; ) run("cp " CPOPTS " " + src + entries[idx] + " " + dest); chdir(dest); for (idx = listlen(entries); idx--; ) logLink(entries[idx]); } c++-annotations-12.5.0/icmake/logzip0000644000175000017500000000134514466730207016162 0ustar frankfrank// names may be a series of files in src, not a wildcard. // if it's empty then all files in src are used. // the files are gzipped and logged in dest. // src and dest do not have to end in / void logZip(string src, string names, string dest) { list files; int idx; string file; chdir(g_cwd); dest += "/"; md(dest); if (src != "") chdir(src); if (names == "") files = makelist("*"); else files = strtok(names, " "); for (idx = listlen(files); idx--; ) { file = files[idx]; run("gzip -n -9 < " + file + " > " + g_cwd + dest + file + ".gz"); } chdir(g_cwd + dest); for (idx = listlen(files); idx--; ) log(files[idx] + ".gz"); } c++-annotations-12.5.0/icmake/distclean0000644000175000017500000000114614466730207016623 0ustar frankfrankvoid distclean() { list extensions; int idx; clean(0); run("rm -f script.log yo/legal.shtml latex/legal.shtml html/legal.shtml"); run("rm -f html/cplusplus*.html"); run("rm -f html/target.shtml html/contents.html html/index.html"); run("rm -f html/cppindex.html html/cplusplus.index zip/cplusplus.*.zip"); extensions = strtok("aux dvi idx ilg ind latex log out pdf ps toc", " "); for(idx = listlen(extensions); idx--; ) run("rm -f latex/cplusplus*." + extensions[idx]); run("rm -rf src/*/*/o src/*/o"); run("rm -rf zip/cplusplus.txt"); exit(0); } c++-annotations-12.5.0/icmake/docs0000644000175000017500000001440714624636422015611 0ustar frankfrankstring stringlist(string path, string subdir, string pattern) { list lst; string entry; int idx; string ret; path += subdir + "/"; chdir(subdir); lst = makelist(O_SUBDIR, "*"); for (idx = listlen(lst); idx--; ) ret += stringlist(path, element(idx, lst), pattern); lst = makelist(pattern); for (idx = listlen(lst); idx--; ) ret += path + element(idx, lst) + " "; chdir(".."); return ret; } void cleanup(string task, string files) { list filelist; int idx; filelist = strtok(files, " "); for (idx = listlen(filelist); idx--; ) system("tmp/bin/" + task + " -q " + element(idx, filelist)); } void txtdoc() { if (!exists("tmp/docs/txt/cplusplus.txt")) { md("tmp/docs/txt"); chdir("yo"); system("yodl2txt --no-warnings " "-o ../tmp/docs/txt/cplusplus.txt -l3 cplusplus"); chdir(".."); } } void htmldoc() { list htmlList; int idx; string html; md("tmp/docs/html"); // cp necessary files for HTML if (!exists("tmp/docs/html/annotations.gif")) system("cp -r html/* tmp/docs/html"); // convert .yo to .html if (!exists("tmp/docs/html/cplusplus.html")) { chdir("yo"); system("yodl2html --no-warnings -l3 cplusplus "); system("mv *.html ../tmp/docs/html"); system("cp cplusplus.css ../tmp/docs/html"); chdir(".."); } chdir("tmp/docs/html"); // only in 2024 system("../../../tmp/bin/celeb cplusplus.html"); // index.html is the file holding the // c++-annotations-12.5.0/single/target.shtml0000644000175000017500000000440414466730207017321 0ustar frankfrank C++ Annotations

Table of contents:

Contents

Title Page

  1. All Chapters
  2. C++ Intro
  3. A First Impression
  4. Name Spaces
  5. Strings
  6. IOStreams
  7. Classes
  8. Static Data And Functions
  9. Memory Management
  10. Exceptions
  11. Operator Overloading
  12. Abstract Containers
  13. Inheritance
  14. Polymorphism
  15. Friends
  16. Pointers to Members
  17. Nested Classes
  18. Standard Template Library
  19. Generic Algorithms
  20. Multi Threading
  21. Function Templates
  22. Class Templates
  23. Advanced Template Use
  24. Coroutines
  25. Examples

Index

Index:

c++-annotations-12.5.0/single/legal.shtml0000644000175000017500000000215114466730207017114 0ustar frankfrank Legal considerations for the C++ Annotations


Legal considerations for the C++ Annotations

The C++ Annotations are distributed under the GNU General Public License version 2 or later (See the file COPYING distributed with the C++ Annotations's distribution).

You are encouraged to read the C++ Annotations and to share the C++ Annotations with others. You are also encouraged to include links to the C++ Annotations in your own WWW documents and you are allowed to publish the C++ Annotations on your web-site.

If you intend to use the C++ Annotations for educational purposes please let me know: the more people tell me they use them, the easier it becomes for me to continue and maintain the C++ Annotations.

Direct all correspondence concerning suggestions, additions, improvements or changes in this document to Frank B. Brokken.

The document itself starts here. c++-annotations-12.5.0/src/0000755000175000017500000000000014624636054014267 5ustar frankfrankc++-annotations-12.5.0/src/tab/0000755000175000017500000000000014466730207015034 5ustar frankfrankc++-annotations-12.5.0/src/tab/fname.c0000644000175000017500000000042514466730207016267 0ustar frankfrank#include #ifdef MSDOS #define SEP '\\' #else #define SEP '/' #endif char *fname(char *prog) { register char *cp; if ( (cp = strrchr(prog, SEP)) ) cp++; else cp = prog; # ifdef MSDOS *strstr (cp, ".EXE") = '\0'; # endif return (cp); } c++-annotations-12.5.0/src/tab/flex.c0000644000175000017500000013710614466730207016146 0ustar frankfrank#define YY_NO_INPUT #line 2 "flex.c" #line 4 "flex.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex. yyunput not compiled: by Frank */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 33 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ #if __STDC__ #define YY_USE_CONST #endif /* __STDC__ */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). */ #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef unsigned int yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 0; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) typedef unsigned char YY_CHAR; FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; typedef int yy_state_type; extern int yylineno; int yylineno = 1; extern char *yytext; #define yytext_ptr yytext static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 5 #define YY_END_OF_BUFFER 6 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[9] = { 0, 0, 0, 6, 4, 2, 3, 1, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[5] = { 0, 1, 1, 1, 1 } ; static yyconst flex_int16_t yy_base[9] = { 0, 0, 0, 5, 6, 6, 6, 6, 6 } ; static yyconst flex_int16_t yy_def[9] = { 0, 8, 1, 8, 8, 8, 8, 8, 0 } ; static yyconst flex_int16_t yy_nxt[11] = { 0, 4, 5, 6, 7, 8, 3, 8, 8, 8, 8 } ; static yyconst flex_int16_t yy_chk[11] = { 0, 1, 1, 1, 1, 3, 8, 8, 8, 8, 8 } ; static yy_state_type yy_last_accepting_state; static char *yy_last_accepting_cpos; extern int yy_flex_debug; int yy_flex_debug = 0; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; #line 1 "rules.lex" #line 2 "rules.lex" int column = 0, nspaces = 0; FILE *yyout; extern int entab, minspaces, tabpos; void process_spaces() { register int ntabs; if (nspaces >= minspaces) if ( (ntabs = column / tabpos - (column - nspaces) / tabpos) ) { nspaces = column % tabpos; for (; ntabs; ntabs--) fputc('\t', yyout); /* put out a tab char */ } while (nspaces--) fputc(' ', yyout); nspaces = 0; } #line 482 "flex.c" #define INITIAL 0 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif static int yy_init_globals (void ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif #if 0 static void yyunput (int c,char *buf_ptr ); #endif #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 32 "rules.lex" #line 637 "flex.c" if ( !(yy_init) ) { (yy_init) = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 9 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 6 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = (yy_hold_char); yy_cp = (yy_last_accepting_cpos); yy_current_state = (yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP #line 33 "rules.lex" { column++; nspaces++; if (!entab) /* write blank if detab */ fputc(' ', yyout); } YY_BREAK case 2: YY_RULE_SETUP #line 41 "rules.lex" { if (entab) { process_spaces(); fputc('\t', yyout); } else { do fputc(' ', yyout); while (++column % tabpos); } column = 0; /* as we are at a tab-position */ } YY_BREAK case 3: /* rule 3 can match eol */ YY_RULE_SETUP #line 56 "rules.lex" { fputc(yytext[0], yyout); column = nspaces = 0; /* process spaces are ignored */ } YY_BREAK case 4: YY_RULE_SETUP #line 61 "rules.lex" { if (entab) process_spaces(); column++; fputc(yytext[0], yyout); } YY_BREAK case 5: YY_RULE_SETUP #line 67 "rules.lex" ECHO; YY_BREAK #line 773 "flex.c" case YY_STATE_EOF(INITIAL): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) ((yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), (size_t) num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 9 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { register int yy_is_jam; register char *yy_cp = (yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { (yy_last_accepting_state) = yy_current_state; (yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 9 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 8); return yy_is_jam ? 0 : yy_current_state; } #if 0 static void yyunput (int c, register char * yy_bp ) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register int number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } #ifndef __cplusplus extern int isatty (int ); #endif /* __cplusplus */ /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { int num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) { return yy_scan_bytes(yystr,strlen(yystr) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param bytes the byte buffer to scan * @param len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ int yyget_lineno (void) { return yylineno; } /** Get the input stream. * */ FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ int yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param line_number * */ void yyset_lineno (int line_number ) { yylineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * in_str ) { yyin = in_str ; } void yyset_out (FILE * out_str ) { yyout = out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int bdebug ) { yy_flex_debug = bdebug ; } static int yy_init_globals (void) { /* Initialization is the same as for the non-reentrant scanner. * This function is called from yylex_destroy(), so don't allocate here. */ (yy_buffer_stack) = 0; (yy_buffer_stack_top) = 0; (yy_buffer_stack_max) = 0; (yy_c_buf_p) = (char *) 0; (yy_init) = 0; (yy_start) = 0; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = (FILE *) 0; yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * yylex_init() */ return 0; } /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * yylex() is called, initialization will occur. */ yy_init_globals( ); return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 67 "rules.lex" c++-annotations-12.5.0/src/tab/tab.c0000644000175000017500000001036614466730207015754 0ustar frankfrank/* TAB.C 92 11 24 Ported for Unix KK 94 04 06 Port and maintenance for ELF: FBB 96/08/xx Skipping symbolic links: FBB 2001/07/22 Repairing EOF swallow: FBB 2001/09/09 */ #ifdef MSDOS #if !defined(M_I86SM) #error SMALL memory model expected #endif #endif #include #include #include #ifndef MSDOS #include #include #include #endif extern int yylex (void); extern char *fname (char *); extern FILE *yyin, *yyout; extern int column, nspaces; int quiet = 0, entab = 0, minspaces = 4, tabpos = 8; char version[] = "1.41", tempfile[] = "tab.tmp"; int main(int argc, char **argv) { int piping = 0; char *progname; struct stat fileinfo; progname = fname(argv[0]); while (argc > 1 && *argv[1] == '-') { switch (argv[1][1]) { case 'd': entab = 0; break; case 'e': entab = 1; break; case 's': if (!(minspaces = atoi(argv [1] + 2))) { printf("%s: missing or illegal space count at -s, " "assuming 4\n", progname); minspaces = 4; } break; case 'c': if (!(tabpos = atoi(argv [1] + 2))) { printf("%s: missing or illegal column count at -c, " "assuming 8\n", progname); tabpos = 8; } break; case 'q': quiet = 1; break; default: if (!argv[1][1]) { piping = 1; break; } printf("%s: unknown flag '-%c,' ignored\n", progname, *(*argv + 1)); break; } argv++; argc--; } if (argc == 1 && !piping) /* error */ { printf("\nTAB Entabber/Detabber V%s\n" "Copyright (c) GPL 1989-2006. All rights reserved.\n" "\n" "%s by Frank B. Brokken (f.b.brokken@rc.rug.nl).\n" "\n" "Usage: %s [-d | -e | -snnn | -cnnn]* file(s)\n" "where:\n" " -c - entab at / detab to multiples of nnn columns " "(default: 8)\n" " -d - tabs in file(s) are removed (detab)\n" " (default action)\n" " -e - spaces in file(s) are changed into tabs (entab)\n" " -q - quiet: less output than otherwise\n" " -s - entab/detab a minimum number of nnn spaces " "(default: 4)\n" " file(s) - file(s) to entab/detab (are overwritten)\n" " use - to filter stdin to stdout\n" " non-regular files (e.g. symbolic links) are " "skipped.\n" "\n" , version, progname, progname); return (1); } if (piping) { yyin = stdin; yyout = stdout; yylex(); return (0); } for (++argv; *argv; ++argv) { if (lstat(*argv, &fileinfo)) { printf("Can't stat %s: skipping\n", *argv); continue; } if (!S_ISREG(fileinfo.st_mode)) /* not a regular file */ continue; /* skip it silently */ if (!quiet) printf("processing %s\n", *argv); unlink(tempfile); if (rename(*argv, tempfile)) { printf("%s: can't rename %s\n", progname, *argv); return (1); } if ( !(yyin = fopen(tempfile, "r")) || !(yyout = fopen(*argv, "w")) ) { printf ("%s: cannot open in- or output file\n", progname); return (1); } yylex(); fclose (yyin); fclose (yyout); } unlink(tempfile); return (0); } c++-annotations-12.5.0/src/htmlindex/0000755000175000017500000000000014624645634016267 5ustar frankfrankc++-annotations-12.5.0/src/htmlindex/build0000755000175000017500000001461314466730207017314 0ustar frankfrank#!/usr/bin/icmake -t. #include "../../compilers.im" string CLASSES; void setClasses() { CLASSES += " aux indexentry"; } #define ECHO_REQUEST ON // Extra libraries required. Remove lib and .a from the library names. // E.g., #define LIBS "m Xt" to link libm.a and libXt.a explicitly // Specify libs from the most specific to the most general one. #define LIBS ${BOBCAT} // Extra library-paths required. // E.g., #define LIBPATH "/some/path /some/other/path" to search these paths // apart from the default paths #define LIBPATH ${LPATH} // DO NOT ALTER THINGS BELOW THIS LINE string // contain options for libs, // extra libs, e.g., "-lrss -licce" libpath, // extra lib-paths, eg, "-L../rss" lopt, libxxxa; // expanded lib-name string ofiles, // wildcards for o-files sources, // sources to be used wild, // wildcard of extension current; // contains name of current dir. list objfiles(list files) { string file, objfile; int i; for (i = 0; i < listlen(files); i++) { file = element(i, files); // determine element of the list objfile = "./o/" + change_ext(file, "o"); // make obj-filename if (objfile younger file) // objfile is younger { files -= (list)file; // remove the file from the list i--; // reduce i to test the next } } return (files); } list altered(list files, string target) { int i; string file; for (i = 0; i < listlen(files); i++) // try all elements of the list { file = element(i, files); // use element i of the list if (file older target) // a file is older than the target { files -= (list)file; // remove the file from the list i--; // reduce i to inspect the next } // file of the list } return (files); // return the new list } list file_list(string type, string library) { list files; files = makelist(type); // make all files of certain type files = objfiles(files); // remove if younger .obj exist return (files); } void link(string library, string exe) { exec(GPP, "-o", exe, ofiles, libs, "-L.", libpath, lopt ); } void c_compile(list cfiles) { string nextfile; int i; if (!exists("o")) system("mkdir o"); if (listlen(cfiles)) // files to compile ? { printf(current, "\n"); // compile all files separately for (i = 0; nextfile = element(i, cfiles); i++) { exec(GPP, "-c -o o/" + change_ext(nextfile, "o") + " " CPPOPT + " " + nextfile); } } } void updatelib(string library) { list arlist, objlist; string to, from; objlist = makelist("*.o"); if (!listlen(objlist)) return; printf("\n"); exec("ar", "rvs", library, "*.o"); exec("rm", "*.o"); printf("\n"); } void prefix_class(string class_id) { list o_files; string o_file; int i; o_files = makelist("*.o"); for (i = 0; o_file = element(i, o_files); i++) exec("mv", o_file, class_id + o_file); } void std_cpp(string library) { list cfiles; cfiles = file_list(wild, library); // make list of all cpp-files c_compile(cfiles); // compile cpp-files } void cpp_make(string mainfile, string library, string exe) { int n, index; list classes; string cwd; setClasses(); // remaining classes cwd = chdir("."); ofiles = "o/*.o"; // std set of o-files classes = strtok(CLASSES, " "); // list of classes if (n = listlen(classes)) ofiles += " */o/*.o"; // set ofiles for no LIBRARY use wild = sources; // make library name libxxxa = chdir(".") + "lib" + library + ".a"; // first process all classes for (index = 0; index < n; index++) { current = element(index, classes); // next class to process chdir(current); // change to directory current = "subdir " + current; std_cpp (libxxxa); // compile all files chdir( cwd); // go back to parent dir } current = "auxiliary " + wild + " files"; std_cpp (libxxxa); // compile all files in current dir for (index = 0; index < n; index++) { current = element(index, classes); // determine class name chdir( current); // chdir to a class directory. chdir(cwd); // go back to parent dir } current = ""; // no class anymore if (mainfile != "") // mainfile -> do link link(library, exe); } void setlibs() { int n, index; list cut; cut = strtok(LIBS, " "); // cut op libraries n = listlen(cut); for (index = 0; index < n; index++) libs += " -l" + element(index, cut); cut = strtok(LIBPATH, " "); // cut up the paths n = listlen(cut); for (index = 0; index < n; index++) libpath += " -L" + element(index, cut); } void main() { echo(ECHO_REQUEST); sources = "*.cc"; setlibs(); lopt = "-s"; system("mkdir -p ../../tmp/bin"); // make destination if it doesn't // already exist cpp_make ( "htmlindex.cc", // program source "htmlindex", // program library "../../tmp/bin/htmlindex" // binary program ); } c++-annotations-12.5.0/src/htmlindex/htmlindex.cc0000644000175000017500000000245014466730207020566 0ustar frankfrank/* htmlindex.cc */ #include "htmlindex.h" HashString indexHash; vector indexVector; vector filenameVector; string lastFilename; char indexSection = 'A' - 1; int returnValue = 0; int main(int argc, char **argv) { Arg::initialize("", argc, argv); Arg &arg(Arg::instance()); if (isatty(STDIN_FILENO)) usage(arg.basename()); getKeys(); sort(indexVector.begin(), indexVector.end()); head(); unsigned n = indexVector.size(), halfway = (n + 1) / 2; cout << "\n" << "\n"; // left column as a table for (unsigned idx = 0; idx < halfway; idx++) // print left column { cout << "\n"; display(idx); cout << "\n"; } cout << "
\n" << "\n" << // left column done "\n" << "\n"; // right column as a table for (unsigned idx = halfway; idx < n; idx++) // print right column { cout << "\n"; display(idx); cout << "\n"; } cout << "
\n" << "\n"; // right column done tail(); return returnValue; } c++-annotations-12.5.0/src/htmlindex/indexentry/0000755000175000017500000000000014624645634020460 5ustar frankfrankc++-annotations-12.5.0/src/htmlindex/indexentry/operatorless.cc0000644000175000017500000000065414466730207023511 0ustar frankfrank#include "../htmlindex.h" bool IndexEntry::operator<(IndexEntry const &other) const { if (isalnum(uppercaseKey[0]) && !isalnum(other.uppercaseKey[0])) return false; // alphanumeric entries after special chars if (!isalnum(uppercaseKey[0]) && isalnum(other.uppercaseKey[0])) return true; // special chars before alphanumeric entries return uppercaseKey < other.uppercaseKey; } c++-annotations-12.5.0/src/htmlindex/indexentry/showrefs.cc0000644000175000017500000000062314466730207022623 0ustar frankfrank#include "../htmlindex.h" void IndexEntry::showRefs() { for ( vector >::iterator it = labels.begin(); it != labels.end(); it++ ) cout << " second << " target=info>" << it->second << " \n"; } c++-annotations-12.5.0/src/htmlindex/indexentry/indexentry.cc0000644000175000017500000000056414466730207023160 0ustar frankfrank#include "../htmlindex.h" IndexEntry::IndexEntry(string const &keystring, unsigned filenameIndex, unsigned labelNr) : key(keystring) { for (string::iterator it = key.begin(); it != key.end(); it++) if (*it != ' ') uppercaseKey += toupper(*it); labels.push_back(pair(filenameIndex, labelNr)); } c++-annotations-12.5.0/src/htmlindex/indexentry/indexentry.h0000644000175000017500000000000014466730207023003 0ustar frankfrankc++-annotations-12.5.0/src/htmlindex/man/0000755000175000017500000000000014466730207017035 5ustar frankfrankc++-annotations-12.5.0/src/htmlindex/man/htmlindex.yo0000644000175000017500000000531214466730207021403 0ustar frankfrankCOMMENT( Leave a definition of a label empty if not used. E.g., if you don't have other programs related to this one, use: SUBST(@SEEALSO) () Use bf() for items that should appear literally in commands, etc. use em() for formal names, that should be replaced by actual values in real life. ) SUBST(@SECTION) (1) SUBST(@DATE) (2003) SUBST(@AUTHOR) (Frank B. Brokken (bf(f.b.brokken@rc.rug.nl)).) SUBST(@ORGANIZATION) (Computing Center, University of Groningen.) SUBST(@PROGRAM) (htmlindex) SUBST(@PROJECT) (C++ Annotations Software) SUBST(@DISTRIBUTION) (htmlindex-X.YY.tar.gz) SUBST(@SHORTDESC) (Create html index from Yodl index entries) SUBST(@SYNOPSYS)( @PROGRAM < indexpage > outputpage ) SUBST(@OPTIONS)( startit() it() tt(indexpage): file obtained from Yodl-html pages containing lines like verb( ) which can be created from Yold-macros like COMMENT(Make sure a blank is written behind the backslashes in the following verb()-block.) verb( NEWCOUNTER(htmlAnchor) def(hix)(1)(\ IFDEF(html)\ (label(an+USECOUNTER(htmlAnchor))\ htmlcommand( )\ )\ (IFDEF(latex)\ (latexcommand(\index{)ARG1+latexcommand(}))\ ()\ )) ) using lines like: verb( hix(http://www.xs4all.nl/.../yodl/) ) it() tt(outputpage): indexfile written as a html-page to the standard output, as a two-column table, sorted, clickable entry file, referring back to labels defined in the pages where the index entries were found. E.g., the table contains entries like verb( http://www.xs4all.nl/.../yodl/ 4  ) endit() ) SUBST(@DESCRIPTION)( See the description of the options. The conversion of index entries in the html file to labels within files may be performed by a simple script, like: verb( #!/bin/sh cd ../html for x in `ls cplusplus[0-9][0-9].html` ; do grep -v '^ ${x}2 mv ${x}2 $x done ) ) SUBST(@FILES)(-) SUBST(@SEEALSO)(-) SUBST(@DIAGNOSTICS)(-) SUBST(@BUGS) (No Documented Bugs.) SUBST(@COPYRIGHT)( This is free software, distributed under the terms of the GNU General Public License. ) COMMENT(Do not modify from here) INCLUDEFILE(/usr/local/share/makemanpage/executables.1/pagedef.yo) c++-annotations-12.5.0/src/htmlindex/aux/0000755000175000017500000000000014624645634017064 5ustar frankfrankc++-annotations-12.5.0/src/htmlindex/aux/getkeys.cc0000644000175000017500000000456114466730207021047 0ustar frankfrank#include "../htmlindex.h" void getKeys() { string line; Pattern pattern("([^:]+):"); unsigned filenameIndex = 0; while (getline(cin, line)) { try { pattern.match(line); } catch (...) { cerr << "Invalid entry at line `" << line << "'\n"; returnValue = 1; continue; } Pattern::Position pos = pattern.position(3); if (pos.first == pos.second) { cerr << "Missing key at line `" << line << "'\n"; returnValue = 1; continue; } string filename = pattern[1], key = pattern[3]; unsigned labelNr = atoi(pattern[2].c_str()); if (filename != lastFilename) { filenameIndex = filenameVector.size(); filenameVector.push_back(filename); lastFilename = filename; cerr << "File " << filename << " at " << filenameIndex << endl; } /* hash indexHash contains the key and an idx in `index' where IndexEntry objects are stored. vector index; IndexEntry: contains the key (and for comparisons speedup the lowercase key, and vector of unsigned label numbers. First hash (and index) are filled. */ hash_iterator it = indexHash.find(key); if (it != indexHash.end()) // key already available { //cerr << "duplicate key: " << key; indexVector[it->second].push_back(filenameIndex, labelNr); } else { // new key: add to the hashtable //cerr << "new key: " << key; indexHash.insert ( //hash_map::value_type HashString::value_type ( key, indexVector.size() ) ); //cerr << "..."; // and add to the `index' vector indexVector.push_back(IndexEntry(key, filenameIndex, labelNr)); } //cerr << " inserted\n"; } } c++-annotations-12.5.0/src/htmlindex/aux/usage.cc0000644000175000017500000000113014466730207020465 0ustar frankfrank#include "../htmlindex.h" void usage(string const &basename) { cout << "\n" << basename << " by Frank B. Brokken (f.b.brokken@rug.nl)\n" "\n" "C++ Annotations html index page builder, V. " << version << endl << "Copyright (c) 2001-2006 Frank B. Brokken. GPL.\n" "\n" "Usage: " << basename << " < indexpage > outputpage\n" "Where:\n" " indexpage: file containing `' index entries\n" " outputpage: file to write the index page to (e.g., " "cplusplusidx.html)\n" << endl; exit(1); } c++-annotations-12.5.0/src/htmlindex/aux/head.cc0000644000175000017500000000042614466730207020271 0ustar frankfrank#include "../htmlindex.h" void head() { cout << "\n" "\n" "C++ Annotations HTML Index \n" "\n" "\n" "\n" "\n" "

Index

\n" "\n" "\n" "\n"; } c++-annotations-12.5.0/src/htmlindex/aux/display.cc0000644000175000017500000000106214466730207021032 0ustar frankfrank#include "../htmlindex.h" void display(unsigned idx) { IndexEntry &ie = indexVector[idx]; if (ie.firstChar() > indexSection && isalnum(ie.firstChar())) { indexSection = ie.firstChar(); cout << " \n" "\n" "\n"; } cout << " \n" << " \n"; } c++-annotations-12.5.0/src/htmlindex/aux/tail.cc0000644000175000017500000000015014466730207020313 0ustar frankfrank#include "../htmlindex.h" void tail() { cout << "\n" "\n" "
 

" << indexSection << "

" << ie.getKey() << " \n"; ie.showRefs(); cout << "
\n" "\n"; } c++-annotations-12.5.0/src/htmlindex/version.cc0000644000175000017500000000011714466730207020255 0ustar frankfrank#include "htmlindex.h" char version[] = "1.13", year[] = "2001-2014"; c++-annotations-12.5.0/src/htmlindex/htmlindex.h0000644000175000017500000000275314466730207020436 0ustar frankfrank// htmlindex.h #ifndef _H_htmlindex_ #define _H_htmlindex_ #include #include #include #include #include #include #include #include #include using namespace FBB; using namespace std; void usage(string const &basename); void getKeys(); void head(); void display(unsigned idx); void tail(); extern char indexSection, version[], year[]; extern int returnValue; extern string lastFilename; extern vector filenameVector; extern HashString // hash_map indexHash; typedef HashString::iterator // hash_map::iterator hash_iterator; class IndexEntry { public: IndexEntry(string const &key, unsigned filenameIndex, unsigned labelNr); void push_back(unsigned filenameIndex, unsigned labelNr) { labels.push_back(pair(filenameIndex, labelNr)); } bool operator<(IndexEntry const &other) const; string const &getKey() { return key; } char firstChar() { return uppercaseKey[0]; } void showRefs(); private: string uppercaseKey, key; vector > labels; }; extern vector indexVector; #endif c++-annotations-12.5.0/src/verb/0000755000175000017500000000000014466730207015224 5ustar frankfrankc++-annotations-12.5.0/src/verb/usage.cc0000644000175000017500000000170214466730207016637 0ustar frankfrank// usage.cc #include "main.ih" namespace { char const info[] = R"_( [options] file(s) Where: [options] - optional arguments (short options between parentheses): --help (-h) - provide this help --version (-v) - show version information and terminate --replace (-r) - replace .yo files by generated '.yo.vb' files. file(s) - names of files where verb(...) macros must be compacted. Processed files receive extra .vb extensions. Use file:filename (no blanks) as single argument if the files to process are read from lines in 'filename' (empty lines, lines starting with # are ignored) )_"; } void usage(std::string const &progname) { cout << "\n" << progname << " by " << Icmbuild::author << "\n" << progname << " V" << Icmbuild::version << " " << Icmbuild::years << "\n" "\n" "Usage: " << progname << info; } c++-annotations-12.5.0/src/verb/parser/0000755000175000017500000000000014466730207016520 5ustar frankfrankc++-annotations-12.5.0/src/verb/parser/parser.h0000644000175000017500000000320414466730207020164 0ustar frankfrank// Generated by Bisonc++ V6.03.00 on Fri, 08 Nov 2019 10:01:15 +0530 #ifndef Parser_h_included #define Parser_h_included #include #include #include "parserbase.h" #include "../scanner/scanner.h" #undef Parser // CAVEAT: between the baseclass-include directive and the // #undef directive in the previous line references to Parser // are read as ParserBase. // If you need to include additional headers in this file // you should do so after these comment-lines. class Parser: public ParserBase { enum VerbContext { NO, BEGIN, END }; VerbContext d_verbContext = NO; std::string d_blanks; std::ifstream d_in; std::ofstream d_out; // $insert scannerobject Scanner d_scanner; public: Parser(std::string const &fname); int parse(); private: void outBlanks(); // collected blanks to d_out void out(); // d_scanner.matched() to d_out void blankOut(); // outBlanks + out void error(); // called on (syntax) errors int lex(); // returns the next token from the // lexical scanner. void print(); // use, e.g., d_token, d_loc void exceptionHandler(std::exception const &exc); // support functions for parse(): void executeAction_(int ruleNr); void errorRecovery_(); void nextCycle_(); void nextToken_(); void print_(); }; #endif c++-annotations-12.5.0/src/verb/parser/parser1.cc0000644000175000017500000000027614466730207020411 0ustar frankfrank#include "parser.ih" Parser::Parser(string const &fname) : d_in( Exception::factory(fname) ), d_out(Exception::factory(fname + ".vb") ), d_scanner(d_in) {} c++-annotations-12.5.0/src/verb/parser/lex.cc0000644000175000017500000000111414466730207017614 0ustar frankfrank#include "parser.ih" int Parser::lex() { int token; while (true) { token = d_scanner.lex(); if (token != WS) break; d_blanks += d_scanner.matched(); } switch (d_verbContext) { case BEGIN: if (size_t pos = d_blanks.find_last_of('\n'); pos != string::npos) d_blanks.erase(0, pos + 1); d_verbContext = NO; break; case END: d_blanks = '\n'; d_verbContext = NO; break; default: break; } return token; } c++-annotations-12.5.0/src/verb/parser/parse.cc0000644000175000017500000004557514466730207020161 0ustar frankfrank// Generated by Bisonc++ V6.03.00 on Sat, 09 Nov 2019 12:08:40 +0530 // base/comment // $insert class.ih #include "parser.ih" // The FIRST element of SR arrays shown below uses `d_type', defining the // state's type, and `d_lastIdx' containing the last element's index. If // d_lastIdx contains the REQ_TOKEN bitflag (see below) then the state needs // a token: if in this state d_token is Reserved_::UNDETERMINED_, nextToken() will be // called // The LAST element of SR arrays uses `d_token' containing the last retrieved // token to speed up the (linear) seach. Except for the first element of SR // arrays, the field `d_action' is used to determine what to do next. If // positive, it represents the next state (used with SHIFT); if zero, it // indicates `ACCEPT', if negative, -d_action represents the number of the // rule to reduce to. // `lookup()' tries to find d_token in the current SR array. If it fails, and // there is no default reduction UNEXPECTED_TOKEN_ is thrown, which is then // caught by the error-recovery function. // The error-recovery function will pop elements off the stack until a state // having bit flag ERR_ITEM is found. This state has a transition on errTok_ // which is applied. In this errTok_ state, while the current token is not a // proper continuation, new tokens are obtained by nextToken(). If such a // token is found, error recovery is successful and the token is // handled according to the error state's SR table and parsing continues. // During error recovery semantic actions are ignored. // A state flagged with the DEF_RED flag will perform a default // reduction if no other continuations are available for the current token. // The ACCEPT STATE never shows a default reduction: when it is reached the // parser returns ACCEPT(). During the grammar // analysis phase a default reduction may have been defined, but it is // removed during the state-definition phase. // So: // s_x[] = // { // [_field_1_] [_field_2_] // // First element: {state-type, idx of last element}, // Other elements: {required token, action to perform}, // ( < 0: reduce, // 0: ACCEPT, // > 0: next state) // } // base/declarations namespace // anonymous { char const author[] = "Frank B. Brokken (f.b.brokken@rug.nl)"; enum Reserved_ { UNDETERMINED_ = -2, EOF_ = -1, errTok_ = 256 }; enum StateType // modify statetype/data.cc when this enum changes { NORMAL, ERR_ITEM, REQ_TOKEN, ERR_REQ, // ERR_ITEM | REQ_TOKEN DEF_RED, // state having default reduction ERR_DEF, // ERR_ITEM | DEF_RED REQ_DEF, // REQ_TOKEN | DEF_RED ERR_REQ_DEF // ERR_ITEM | REQ_TOKEN | DEF_RED }; inline bool operator&(StateType lhs, StateType rhs) { return (static_cast(lhs) & rhs) != 0; } enum StateTransition { ACCEPT_ = 0, // `ACCEPT' TRANSITION }; struct PI_ // Production Info { size_t d_nonTerm; // identification number of this production's // non-terminal size_t d_size; // number of elements in this production }; struct SR_ // Shift Reduce info, see its description above { union { int _field_1_; // initializer, allowing initializations // of the SR s_[] arrays StateType d_type; int d_token; }; union { int _field_2_; int d_lastIdx; // if negative, the state uses SHIFT int d_action; // may be negative (reduce), // postive (shift), or 0 (accept) }; }; // $insert staticdata enum // size to expand the state-stack with when { // full STACK_EXPANSION_ = 10 }; // Productions Info Records: PI_ const s_productionInfo[] = { {0, 0}, // not used: reduction values are negative {260, 1}, // 1: startrule -> inputtext {261, 2}, // 2: inputtext -> inputtext input {261, 1}, // 3: inputtext -> input {262, 1}, // 4: input (TXT) -> TXT {262, 1}, // 5: input -> verb {263, 3}, // 6: verb (')') -> verbTok content ')' {264, 1}, // 7: verbTok (VERB) -> VERB {265, 2}, // 8: content -> content info {265, 0}, // 9: content -> {266, 3}, // 10: info -> openPar content closePar {266, 1}, // 11: info (TXT) -> TXT {266, 1}, // 12: info -> verbblock {267, 1}, // 13: openPar ('(') -> '(' {268, 1}, // 14: closePar (')') -> ')' {269, 3}, // 15: verbblock (')') -> verbNest content ')' {270, 1}, // 16: verbNest (VERB) -> VERB {271, 1}, // 17: startrule_$ -> startrule }; // State info and SR_ transitions for each state. SR_ s_0[] = { { { REQ_TOKEN}, { 8} }, { { 260}, { 1} }, // startrule { { 261}, { 2} }, // inputtext { { 262}, { 3} }, // input { { 257}, { 4} }, // TXT { { 263}, { 5} }, // verb { { 264}, { 6} }, // verbTok { { 258}, { 7} }, // VERB { { 0}, { 0} }, }; SR_ s_1[] = { { { REQ_TOKEN}, { 2} }, { { EOF_}, { ACCEPT_} }, { { 0}, { 0} }, }; SR_ s_2[] = { { { REQ_DEF}, { 6} }, { { 262}, { 8} }, // input { { 257}, { 4} }, // TXT { { 263}, { 5} }, // verb { { 264}, { 6} }, // verbTok { { 258}, { 7} }, // VERB { { 0}, { -1} }, }; SR_ s_3[] = { { { DEF_RED}, { 1} }, { { 0}, { -3} }, }; SR_ s_4[] = { { { DEF_RED}, { 1} }, { { 0}, { -4} }, }; SR_ s_5[] = { { { DEF_RED}, { 1} }, { { 0}, { -5} }, }; SR_ s_6[] = { { { DEF_RED}, { 2} }, { { 265}, { 9} }, // content { { 0}, { -9} }, }; SR_ s_7[] = { { { DEF_RED}, { 1} }, { { 0}, { -7} }, }; SR_ s_8[] = { { { DEF_RED}, { 1} }, { { 0}, { -2} }, }; SR_ s_9[] = { { { REQ_TOKEN}, { 9} }, { { 41}, { 10} }, // ')' { { 266}, { 11} }, // info { { 267}, { 12} }, // openPar { { 257}, { 13} }, // TXT { { 269}, { 14} }, // verbblock { { 40}, { 15} }, // '(' { { 270}, { 16} }, // verbNest { { 258}, { 17} }, // VERB { { 0}, { 0} }, }; SR_ s_10[] = { { { DEF_RED}, { 1} }, { { 0}, { -6} }, }; SR_ s_11[] = { { { DEF_RED}, { 1} }, { { 0}, { -8} }, }; SR_ s_12[] = { { { DEF_RED}, { 2} }, { { 265}, { 18} }, // content { { 0}, { -9} }, }; SR_ s_13[] = { { { DEF_RED}, { 1} }, { { 0}, { -11} }, }; SR_ s_14[] = { { { DEF_RED}, { 1} }, { { 0}, { -12} }, }; SR_ s_15[] = { { { DEF_RED}, { 1} }, { { 0}, { -13} }, }; SR_ s_16[] = { { { DEF_RED}, { 2} }, { { 265}, { 19} }, // content { { 0}, { -9} }, }; SR_ s_17[] = { { { DEF_RED}, { 1} }, { { 0}, { -16} }, }; SR_ s_18[] = { { { REQ_TOKEN}, { 10} }, { { 268}, { 20} }, // closePar { { 266}, { 11} }, // info { { 41}, { 21} }, // ')' { { 267}, { 12} }, // openPar { { 257}, { 13} }, // TXT { { 269}, { 14} }, // verbblock { { 40}, { 15} }, // '(' { { 270}, { 16} }, // verbNest { { 258}, { 17} }, // VERB { { 0}, { 0} }, }; SR_ s_19[] = { { { REQ_TOKEN}, { 9} }, { { 41}, { 22} }, // ')' { { 266}, { 11} }, // info { { 267}, { 12} }, // openPar { { 257}, { 13} }, // TXT { { 269}, { 14} }, // verbblock { { 40}, { 15} }, // '(' { { 270}, { 16} }, // verbNest { { 258}, { 17} }, // VERB { { 0}, { 0} }, }; SR_ s_20[] = { { { DEF_RED}, { 1} }, { { 0}, { -10} }, }; SR_ s_21[] = { { { DEF_RED}, { 1} }, { { 0}, { -14} }, }; SR_ s_22[] = { { { DEF_RED}, { 1} }, { { 0}, { -15} }, }; // State array: SR_ *s_state[] = { s_0, s_1, s_2, s_3, s_4, s_5, s_6, s_7, s_8, s_9, s_10, s_11, s_12, s_13, s_14, s_15, s_16, s_17, s_18, s_19, s_20, s_21, s_22, }; } // anonymous namespace ends // If the parsing function call (i.e., parse()' needs arguments, then provide // an overloaded function. The code below doesn't rely on parameters, so no // arguments are required. Furthermore, parse uses a function try block to // allow us to do ACCEPT and ABORT from anywhere, even from within members // called by actions, simply throwing the appropriate exceptions. // base/base1 ParserBase::ParserBase() : d_token(Reserved_::UNDETERMINED_), // $insert baseclasscode d_requiredTokens_(0) { } // base/clearin void ParserBase::clearin_() { d_nErrors_ = 0; d_stackIdx = -1; d_stateStack.clear(); d_token = Reserved_::UNDETERMINED_; d_next = TokenPair{ Reserved_::UNDETERMINED_, STYPE_{} }; d_recovery = false; d_acceptedTokens_ = d_requiredTokens_; d_val_ = STYPE_{}; push_(0); } // base/debugfunctions void ParserBase::setDebug(bool mode) { d_actionCases_ = false; d_debug_ = mode; } void ParserBase::setDebug(DebugMode_ mode) { d_actionCases_ = mode & ACTIONCASES; d_debug_ = mode & ON; } // base/lex void ParserBase::lex_(int token) { d_token = token; if (d_token <= 0) d_token = Reserved_::EOF_; d_terminalToken = true; } // base/lookup int ParserBase::lookup_() const { // if the final transition is negative, then we should reduce by the rule // given by its positive value. SR_ const *sr = s_state[d_state]; SR_ const *last = sr + sr->d_lastIdx; for ( ; ++sr != last; ) // visit all but the last SR entries { if (sr->d_token == d_token) return sr->d_action; } if (sr == last) // reached the last element { if (sr->d_action < 0) // default reduction { return sr->d_action; } // No default reduction, so token not found, so error. throw UNEXPECTED_TOKEN_; } // not at the last element: inspect the nature of the action // (< 0: reduce, 0: ACCEPT, > 0: shift) int action = sr->d_action; return action; } // base/pop void ParserBase::pop_(size_t count) { if (d_stackIdx < static_cast(count)) { ABORT(); } d_stackIdx -= count; d_state = d_stateStack[d_stackIdx].first; d_vsp = &d_stateStack[d_stackIdx]; } // base/poptoken void ParserBase::popToken_() { d_token = d_next.first; d_val_ = std::move(d_next.second); d_next.first = Reserved_::UNDETERMINED_; } // base/push void ParserBase::push_(size_t state) { size_t currentSize = d_stateStack.size(); if (stackSize_() == currentSize) { size_t newSize = currentSize + STACK_EXPANSION_; d_stateStack.resize(newSize); } ++d_stackIdx; d_stateStack[d_stackIdx] = StatePair{ d_state = state, std::move(d_val_) }; d_vsp = &d_stateStack[d_stackIdx]; if (d_stackIdx == 0) { } else { } } // base/pushtoken void ParserBase::pushToken_(int token) { d_next = TokenPair{ d_token, std::move(d_val_) }; d_token = token; } // base/redotoken void ParserBase::redoToken_() { if (d_token != Reserved_::UNDETERMINED_) pushToken_(d_token); } // base/reduce void ParserBase::reduce_(int rule) { PI_ const &pi = s_productionInfo[rule]; d_token = pi.d_nonTerm; pop_(pi.d_size); d_terminalToken = false; } // base/shift void ParserBase::shift_(int action) { push_(action); popToken_(); // token processed if (d_recovery and d_terminalToken) { d_recovery = false; d_acceptedTokens_ = 0; } } // base/startrecovery void ParserBase::startRecovery_() { int lastToken = d_token; // give the unexpected token a // chance to be processed // again. pushToken_(Reserved_::errTok_); // specify errTok_ as next token push_(lookup_()); // push the error state d_token = lastToken; // reactivate the unexpected // token (we're now in an // ERROR state). d_recovery = true; } // base/top inline size_t ParserBase::top_() const { return d_stateStack[d_stackIdx].first; } // derived/errorrecovery void Parser::errorRecovery_() { // When an error has occurred, pop elements off the stack until the top // state has an error-item. If none is found, the default recovery // mode (which is to abort) is activated. // // If EOF is encountered without being appropriate for the current state, // then the error recovery will fall back to the default recovery mode. // (i.e., parsing terminates) if (d_acceptedTokens_ >= d_requiredTokens_)// only generate an error- { // message if enough tokens ++d_nErrors_; // were accepted. Otherwise error(); // simply skip input } // get the error state while (not (s_state[top_()][0].d_type & ERR_ITEM)) { pop_(); } // In the error state, looking up a token allows us to proceed. // Continuation may be require multiple reductions, but eventually a // terminal-token shift is used. See nextCycle_ for details. startRecovery_(); } // derived/executeaction void Parser::executeAction_(int production) try { if (token_() != Reserved_::UNDETERMINED_) pushToken_(token_()); // save an already available token switch (production) { // $insert actioncases case 1: #line 13 "grammar" { d_out << '\n'; } break; case 2: #line 20 "grammar" { d_val_ = vs_(-1); } break; case 3: #line 22 "grammar" { d_val_ = vs_(0); } break; case 4: #line 26 "grammar" { blankOut(); } break; case 5: #line 31 "grammar" { d_val_ = vs_(0); } break; case 6: #line 35 "grammar" { d_blanks.clear(); d_out << ")\n"; d_verbContext = END; d_scanner.verbEnds(); } break; case 7: #line 45 "grammar" { d_verbContext = BEGIN; d_out << d_blanks << "verb("; d_blanks.clear(); } break; case 8: #line 54 "grammar" { d_val_ = vs_(-1); } break; case 10: #line 60 "grammar" { d_val_ = vs_(-2); } break; case 11: #line 62 "grammar" { blankOut(); } break; case 12: #line 67 "grammar" { d_val_ = vs_(0); } break; case 13: #line 71 "grammar" { blankOut(); } break; case 14: #line 78 "grammar" { blankOut(); } break; case 15: #line 85 "grammar" { blankOut(); } break; case 16: #line 92 "grammar" { blankOut(); } break; } } catch (std::exception const &exc) { exceptionHandler(exc); } // derived/nextcycle void Parser::nextCycle_() try { if (s_state[state_()]->d_type & REQ_TOKEN) nextToken_(); // obtain next token int action = lookup_(); // lookup d_token in d_state if (action > 0) // SHIFT: push a new state { shift_(action); return; } if (action < 0) // REDUCE: execute and pop. { if (recovery_()) redoToken_(); else executeAction_(-action); // next token is the rule's LHS reduce_(-action); return; } if (recovery_()) ABORT(); else ACCEPT(); } catch (ErrorRecovery_) { if (not recovery_()) errorRecovery_(); else { if (token_() == Reserved_::EOF_) ABORT(); popToken_(); // skip the failing token } } // derived/nexttoken void Parser::nextToken_() { // If d_token is Reserved_::UNDETERMINED_ then if savedToken_() is // Reserved_::UNDETERMINED_ another token is obtained from lex(). Then // savedToken_() is assigned to d_token. // no need for a token: got one already if (token_() != Reserved_::UNDETERMINED_) { return; } if (savedToken_() != Reserved_::UNDETERMINED_) { popToken_(); // consume pending token } else { ++d_acceptedTokens_; // accept another token (see // errorRecover()) lex_(lex()); print_(); } print(); } // derived/print void Parser::print_() { // $insert print } // derived/parse int Parser::parse() try { // The parsing algorithm: // Initially, state 0 is pushed on the stack, and all relevant variables // are initialized by Base::clearin_. // // Then, in an eternal loop: // // 1. If a state is a REQ_TOKEN type, then the next token is obtained // from nextToken(). This may very well be the currently available // token. When retrieving a terminal token d_terminal is set to true. // // 2. lookup() is called, d_token is looked up in the current state's // SR_ array. // // 4. Depending on the result of the lookup() function the next state is // shifted on the parser's stack, a reduction by some rule is applied, // or the parsing function returns ACCEPT(). When a reduction is // called for, any action that may have been defined for that // reduction is executed. // // 5. An error occurs if d_token is not found, and the state has no // default reduction. clearin_(); // initialize, push(0) while (true) { // $insert prompt nextCycle_(); } } catch (Return_ retValue) { return retValue or d_nErrors_; } // derived/tail c++-annotations-12.5.0/src/verb/parser/outblanks.cc0000644000175000017500000000021314466730207021025 0ustar frankfrank#include "parser.ih" void Parser::outBlanks() { if (d_blanks.empty()) return; d_out << d_blanks; d_blanks.clear(); } c++-annotations-12.5.0/src/verb/parser/out.cc0000644000175000017500000000012114466730207017630 0ustar frankfrank#include "parser.ih" void Parser::out() { d_out << d_scanner.matched(); } c++-annotations-12.5.0/src/verb/parser/parser.ih0000644000175000017500000000137714466730207020346 0ustar frankfrank// Generated by Bisonc++ V6.03.00 on Fri, 08 Nov 2019 10:01:15 +0530 // Include this file in the sources of the class Parser. // $insert class.h #include "parser.h" #include inline void Parser::error() { std::cerr << "Syntax error\n"; } inline void Parser::print() { } inline void Parser::exceptionHandler(std::exception const &exc) { throw; // re-implement to handle exceptions thrown by actions } // Add here includes that are only required for the compilation // of Parser's sources. // UN-comment the next using-declaration if you want to use // int Parser's sources symbols from the namespace std without // specifying std:: using namespace std; using namespace FBB; c++-annotations-12.5.0/src/verb/parser/blankout.cc0000644000175000017500000000011614466730207020644 0ustar frankfrank#include "parser.ih" void Parser::blankOut() { outBlanks(); out(); } c++-annotations-12.5.0/src/verb/parser/grammar0000644000175000017500000000222514466730207020072 0ustar frankfrank//%default-actions quiet %filenames parser %scanner ../scanner/scanner.h //%baseclass-preinclude x.h or %token TXT VERB WS %% startrule: inputtext { d_out << '\n'; } ; inputtext: inputtext input | input ; input: TXT { blankOut(); } | verb ; verb: verbTok content ')' // outer block { d_blanks.clear(); d_out << ")\n"; d_verbContext = END; d_scanner.verbEnds(); } ; verbTok: VERB { d_verbContext = BEGIN; // starts an outer verb block d_out << d_blanks << "verb("; d_blanks.clear(); } ; content: content info | // empty ; info: openPar content closePar | TXT { blankOut(); } | verbblock ; openPar: '(' { blankOut(); } ; closePar: ')' { blankOut(); } ; verbblock: verbNest content ')' { blankOut(); } ; verbNest: // not completely OK: nested verb( and VERB // verb(\ [))] are treated identically { blankOut(); } ; c++-annotations-12.5.0/src/verb/parser/parserbase.h0000644000175000017500000000752614466730207021032 0ustar frankfrank// Generated by Bisonc++ V6.03.00 on Sat, 09 Nov 2019 12:08:40 +0530 // hdr/includes #ifndef ParserBase_h_included #define ParserBase_h_included #include #include #include // hdr/baseclass namespace // anonymous { struct PI_; } class ParserBase { public: enum DebugMode_ { OFF = 0, ON = 1 << 0, ACTIONCASES = 1 << 1 }; // $insert tokens // Symbolic tokens: enum Tokens_ { TXT = 257, VERB, WS, }; // $insert STYPE typedef int STYPE_; private: // state semval typedef std::pair StatePair; // token semval typedef std::pair TokenPair; int d_stackIdx = -1; std::vector d_stateStack; StatePair *d_vsp = 0; // points to the topmost value stack size_t d_state = 0; TokenPair d_next; int d_token; bool d_terminalToken = false; bool d_recovery = false; protected: enum Return_ { PARSE_ACCEPT_ = 0, // values used as parse()'s return values PARSE_ABORT_ = 1 }; enum ErrorRecovery_ { UNEXPECTED_TOKEN_, }; bool d_actionCases_ = false; // set by options/directives bool d_debug_ = true; size_t d_requiredTokens_; size_t d_nErrors_; // initialized by clearin() size_t d_acceptedTokens_; STYPE_ d_val_; ParserBase(); void ABORT() const; void ACCEPT() const; void ERROR() const; STYPE_ &vs_(int idx); // value stack element idx int lookup_() const; int savedToken_() const; int token_() const; size_t stackSize_() const; size_t state_() const; size_t top_() const; void clearin_(); void errorVerbose_(); void lex_(int token); void popToken_(); void pop_(size_t count = 1); void pushToken_(int token); void push_(size_t nextState); void redoToken_(); bool recovery_() const; void reduce_(int rule); void shift_(int state); void startRecovery_(); public: void setDebug(bool mode); void setDebug(DebugMode_ mode); }; // hdr/abort inline void ParserBase::ABORT() const { throw PARSE_ABORT_; } // hdr/accept inline void ParserBase::ACCEPT() const { throw PARSE_ACCEPT_; } // hdr/error inline void ParserBase::ERROR() const { throw UNEXPECTED_TOKEN_; } // hdr/savedtoken inline int ParserBase::savedToken_() const { return d_next.first; } // hdr/opbitand inline ParserBase::DebugMode_ operator&(ParserBase::DebugMode_ lhs, ParserBase::DebugMode_ rhs) { return static_cast( static_cast(lhs) & rhs); } // hdr/opbitor inline ParserBase::DebugMode_ operator|(ParserBase::DebugMode_ lhs, ParserBase::DebugMode_ rhs) { return static_cast(static_cast(lhs) | rhs); }; // hdr/recovery inline bool ParserBase::recovery_() const { return d_recovery; } // hdr/stacksize inline size_t ParserBase::stackSize_() const { return d_stackIdx + 1; } // hdr/state inline size_t ParserBase::state_() const { return d_state; } // hdr/token inline int ParserBase::token_() const { return d_token; } // hdr/vs inline ParserBase::STYPE_ &ParserBase::vs_(int idx) { return (d_vsp + idx)->second; } // hdr/tail // For convenience, when including ParserBase.h its symbols are available as // symbols in the class Parser, too. #define Parser ParserBase #endif c++-annotations-12.5.0/src/verb/files/0000755000175000017500000000000014466730207016326 5ustar frankfrankc++-annotations-12.5.0/src/verb/files/files.h0000644000175000017500000000112614466730207017601 0ustar frankfrank#ifndef INCLUDED_FILES_ #define INCLUDED_FILES_ #include #include class Files { std::vector d_fname; size_t d_idx = 0; public: Files(); explicit operator bool() const; std::string const &next(); private: void fillArgs(); // add arguments to d_fname void read(std::string const &fname); // or fnames from file }; inline Files::operator bool() const { return d_idx < d_fname.size(); } inline std::string const &Files::next() { return d_fname[d_idx++]; } #endif c++-annotations-12.5.0/src/verb/files/read.cc0000644000175000017500000000070214466730207017547 0ustar frankfrank//#define XERR #include "files.ih" void Files::read(string const &fname) { ifstream in{ Exception::factory(fname) }; string line; while (getline(in, line)) { size_t pos = line.find_first_not_of(" \t"); if (pos == string::npos or line[pos] == '#') // empty or comment? continue; // then skip this line d_fname.push_back(String::trim(line)); } } c++-annotations-12.5.0/src/verb/files/fillargs.cc0000644000175000017500000000031214466730207020434 0ustar frankfrank//#define XERR #include "files.ih" void Files::fillArgs() { Arg const &arg = Arg::instance(); for (size_t idx = 0, end = arg.nArgs(); idx != end; ++idx) d_fname.push_back(arg[idx]); } c++-annotations-12.5.0/src/verb/files/files1.cc0000644000175000017500000000061414466730207020021 0ustar frankfrank//#define XERR #include "files.ih" Files::Files() { string arg0{ Arg::instance()[0] }; size_t pos = arg0.find(':'); // ':' in 1st arg? if (pos == string::npos) // no: just a list of names fillArgs(); // add them to d_fname else read(arg0.substr(pos + 1)); // or read the names fm file } c++-annotations-12.5.0/src/verb/files/files.ih0000644000175000017500000000026614466730207017756 0ustar frankfrank#include "files.h" #include "../xerr.ih" #include #include #include #include using namespace std; using namespace FBB; c++-annotations-12.5.0/src/verb/compactor/0000755000175000017500000000000014466730207017213 5ustar frankfrankc++-annotations-12.5.0/src/verb/compactor/run.cc0000644000175000017500000000071514466730207020331 0ustar frankfrank//#define XERR #include "compactor.ih" void Compactor::run() { bool replace = Arg::instance().option('r'); Files files; while (files) { string fname{ files.next() }; cout << "processing " << fname << '\n'; Parser parser(fname); if (parser.parse() != 0) throw Exception{} << "Error(s) while processing " << fname; if (replace) filesystem::rename(fname + ".vb", fname); } } c++-annotations-12.5.0/src/verb/compactor/compactor1.cc0000644000175000017500000000010714466730207021570 0ustar frankfrank//#define XERR #include "compactor.ih" Compactor::Compactor() //: { } c++-annotations-12.5.0/src/verb/compactor/compactor.ih0000644000175000017500000000040614466730207021524 0ustar frankfrank#include "compactor.h" #include "../xerr.ih" #include #include #include #include #include #include "../parser/parser.h" #include "../files/files.h" using namespace std; using namespace FBB; c++-annotations-12.5.0/src/verb/compactor/compactor.h0000644000175000017500000000024114466730207021350 0ustar frankfrank#ifndef INCLUDED_COMPACTOR_ #define INCLUDED_COMPACTOR_ class Compactor { public: Compactor(); void run(); private: }; #endif c++-annotations-12.5.0/src/verb/scanner/0000755000175000017500000000000014466730207016655 5ustar frankfrankc++-annotations-12.5.0/src/verb/scanner/lex.cc0000644000175000017500000003511114466730207017755 0ustar frankfrank// Generated by Flexc++ V2.07.06 on Sat, 09 Nov 2019 12:08:40 +0530 #include #include #include #include // $insert class_ih #include "scanner.ih" // s_ranges_: use (unsigned) characters as index to obtain // that character's range-number. // The range for EOF is defined in a constant in the // class header file size_t const ScannerBase::s_ranges_[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5, 5, 6, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11, 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,13,14,14,14,14,15,16,17, 17,18,19,19,19,19,19,19,19,19,19,19,19,19,20,21,21,21,22,23,23,23,23,24,24, 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, 24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24, 24,24,24,24,24,24, }; // $insert startcondinfo // s_dfa_ contains the rows of *all* DFAs ordered by start state. The // enum class StartCondition_is defined in the baseclass header. // StartCondition_::INITIAL is always 0. Each entry defines the row to // transit to if the column's character range was sensed. Row numbers are // relative to the used DFA, and d_dfaBase_ is set to the first row of // the subset to use. The row's final two values are respectively the // rule that may be matched at this state, and the rule's FINAL flag. If // the final value equals FINAL (= 1) then, if there's no continuation, // the rule is matched. If the BOL flag (8) is also set (so FINAL + BOL (= // 9) is set) then the rule only matches when d_atBOL is also true. int const ScannerBase::s_dfa_[][28] = { // INITIAL { 1, 2, 2, 1, 2, 1, 3, 3, 1, 4, 1, 4, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 5, 4, 1,-1, -1, -1}, // 0 {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 6, -1}, // 1 {-1, 2, 2,-1, 2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 4, -1}, // 2 {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 5, -1}, // 3 {-1,-1,-1,-1,-1,-1,-1,-1,-1, 4,-1, 4,-1,-1,-1, 4, 4, 4, 4, 4, 4, 4, 4, 4,-1,-1, 3, -1}, // 4 {-1,-1,-1,-1,-1,-1,-1,-1,-1, 4,-1, 4,-1,-1,-1, 4, 4, 4, 6, 4, 4, 4, 4, 4,-1,-1, 3, -1}, // 5 {-1,-1,-1,-1,-1,-1,-1,-1,-1, 4,-1, 4,-1,-1,-1, 4, 4, 4, 4, 4, 7, 4, 4, 4,-1,-1, 3, -1}, // 6 {-1,-1,-1,-1,-1,-1,-1,-1,-1, 4,-1, 4,-1,-1,-1, 4, 8, 4, 4, 4, 4, 4, 4, 4,-1,-1, 3, -1}, // 7 {-1,-1,-1,-1,-1,-1, 9,-1,-1, 4,-1, 4,-1,-1,-1, 4, 4, 4, 4, 4, 4, 4, 4, 4,-1,-1, 0, -1}, // 8 {-1,10,11,-1,10,-1,-1,-1,-1,-1,-1,-1,-1,12,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, -1, -1}, // 9 {-1,10,11,-1,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, -1, -1}, // 10 {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 1, -1}, // 11 {-1,-1,13,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, -1, -1}, // 12 {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1, 2, -1}, // 13 }; int const (*ScannerBase::s_dfaBase_[])[28] = { s_dfa_ + 0, }; size_t ScannerBase::s_istreamNr = 0; // $insert inputImplementation ScannerBase::Input::Input() : d_in(0), d_lineNr(1) {} ScannerBase::Input::Input(std::istream *iStream, size_t lineNr) : d_in(iStream), d_lineNr(lineNr) {} size_t ScannerBase::Input::get() { switch (size_t ch = next()) // get the next input char { case '\n': ++d_lineNr; [[fallthrough]]; default: return ch; } } size_t ScannerBase::Input::next() { size_t ch; if (d_deque.empty()) // deque empty: next char fm d_in { if (d_in == 0) return AT_EOF; ch = d_in->get(); return *d_in ? ch : static_cast(AT_EOF); } ch = d_deque.front(); d_deque.pop_front(); return ch; } void ScannerBase::Input::reRead(size_t ch) { if (ch < 0x100) { if (ch == '\n') --d_lineNr; d_deque.push_front(ch); } } void ScannerBase::Input::reRead(std::string const &str, size_t fm) { for (size_t idx = str.size(); idx-- > fm; ) reRead(str[idx]); } ScannerBase::ScannerBase(std::istream &in, std::ostream &out) : d_filename("-"), d_out(new std::ostream(out.rdbuf())), // $insert interactiveInit d_in(0), d_input(new std::istream(in.rdbuf())), d_dfaBase_(s_dfa_) {} void ScannerBase::switchStream_(std::istream &in, size_t lineNr) { d_input.close(); d_input = Input(new std::istream(in.rdbuf()), lineNr); } ScannerBase::ScannerBase(std::string const &infilename, std::string const &outfilename) : d_filename(infilename), d_out(outfilename == "-" ? new std::ostream(std::cout.rdbuf()) : outfilename == "" ? new std::ostream(std::cerr.rdbuf()) : new std::ofstream(outfilename)), d_input(new std::ifstream(infilename)), d_dfaBase_(s_dfa_) {} void ScannerBase::switchStreams(std::istream &in, std::ostream &out) { switchStream_(in, 1); switchOstream(out); } void ScannerBase::switchOstream(std::ostream &out) { *d_out << std::flush; d_out.reset(new std::ostream(out.rdbuf())); } // $insert debugFunctions void ScannerBase::setDebug(bool onOff) {} bool ScannerBase::debug() const { return false; } void ScannerBase::redo(size_t nChars) { size_t from = nChars >= length() ? 0 : length() - nChars; d_input.reRead(d_matched, from); d_matched.resize(from); } void ScannerBase::switchOstream(std::string const &outfilename) { *d_out << std::flush; d_out.reset( outfilename == "-" ? new std::ostream(std::cout.rdbuf()) : outfilename == "" ? new std::ostream(std::cerr.rdbuf()) : new std::ofstream(outfilename)); } void ScannerBase::switchIstream(std::string const &infilename) { d_input.close(); d_filename = infilename; d_input = Input(new std::ifstream(infilename)); d_atBOL = true; } void ScannerBase::switchStreams(std::string const &infilename, std::string const &outfilename) { switchOstream(outfilename); switchIstream(infilename); } void ScannerBase::pushStream(std::istream &istr) { std::istream *streamPtr = new std::istream(istr.rdbuf()); p_pushStream("(istream)", streamPtr); } void ScannerBase::pushStream(std::string const &name) { std::istream *streamPtr = new std::ifstream(name); if (!*streamPtr) { delete streamPtr; throw std::runtime_error("Cannot read " + name); } p_pushStream(name, streamPtr); } void ScannerBase::p_pushStream(std::string const &name, std::istream *streamPtr) { if (d_streamStack.size() == s_maxSizeofStreamStack_) { delete streamPtr; throw std::length_error("Max stream stack size exceeded"); } d_streamStack.push_back(StreamStruct{d_filename, d_input}); d_filename = name; d_input = Input(streamPtr); d_atBOL = true; } bool ScannerBase::popStream() { d_input.close(); if (d_streamStack.empty()) return false; StreamStruct &top = d_streamStack.back(); d_input = top.pushedInput; d_filename = top.pushedName; d_streamStack.pop_back(); return true; } // See the manual's section `Run-time operations' section for an explanation // of this member. ScannerBase::ActionType_ ScannerBase::actionType_(size_t range) { d_nextState = d_dfaBase_[d_state][range]; if (d_nextState != -1) // transition is possible return ActionType_::CONTINUE; if (knownFinalState()) // FINAL state reached return ActionType_::MATCH; if (d_matched.size()) return ActionType_::ECHO_FIRST; // no match, echo the 1st char return range != s_rangeOfEOF_ ? ActionType_::ECHO_CH : ActionType_::RETURN; } void ScannerBase::accept(size_t nChars) // old name: less { if (nChars < d_matched.size()) { d_input.reRead(d_matched, nChars); d_matched.resize(nChars); } } void ScannerBase::setMatchedSize(size_t length) { d_input.reRead(d_matched, length); // reread the tail section d_matched.resize(length); // return what's left } // At this point a rule has been matched. The next character is not part of // the matched rule and is sent back to the input. The final match length // is determined, the index of the matched rule is determined, and then // d_atBOL is updated. Finally the rule's index is returned. // The numbers behind the finalPtr assignments are explained in the // manual's `Run-time operations' section. size_t ScannerBase::matched_(size_t ch) { d_input.reRead(ch); FinalData *finalPtr; if (not d_atBOL) // not at BOL finalPtr = &d_final.std; // then use the std rule (3, 4) // at BOL else if (not available(d_final.std.rule)) // only a BOL rule avail. finalPtr = &d_final.bol; // use the BOL rule (6) else if (not available(d_final.bol.rule)) // only a std rule is avail. finalPtr = &d_final.std; // use the std rule (7) else if ( // Both are available (8) d_final.bol.length != // check lengths of matched texts d_final.std.length // unequal lengths, use the rule ) // having the longer match length finalPtr = d_final.bol.length > d_final.std.length ? &d_final.bol : &d_final.std; else // lengths are equal: use 1st rule finalPtr = d_final.bol.rule < d_final.std.rule ? &d_final.bol : &d_final.std; setMatchedSize(finalPtr->length); d_atBOL = d_matched.back() == '\n'; return finalPtr->rule; } size_t ScannerBase::getRange_(int ch) // using int to prevent casts { return ch == AT_EOF ? as(s_rangeOfEOF_) : s_ranges_[ch]; } // At this point d_nextState contains the next state and continuation is // possible. The just read char. is appended to d_match void ScannerBase::continue_(int ch) { d_state = d_nextState; if (ch != AT_EOF) d_matched += ch; } void ScannerBase::echoCh_(size_t ch) { *d_out << as(ch); d_atBOL = ch == '\n'; } // At this point there is no continuation. The last character is // pushed back into the input stream as well as all but the first char. in // the buffer. The first char. in the buffer is echoed to stderr. // If there isn't any 1st char yet then the current char doesn't fit any // rules and that char is then echoed void ScannerBase::echoFirst_(size_t ch) { d_input.reRead(ch); d_input.reRead(d_matched, 1); echoCh_(d_matched[0]); } // Update the rules associated with the current state, do this separately // for BOL and std rules. // If a rule was set, update the rule index and the current d_matched // length. void ScannerBase::updateFinals_() { size_t len = d_matched.size(); int const *rf = d_dfaBase_[d_state] + s_finIdx_; if (rf[0] != -1) // update to the latest std rule { d_final.std = FinalData { as(rf[0]), len }; } if (rf[1] != -1) // update to the latest bol rule { d_final.bol = FinalData { as(rf[1]), len }; } } void ScannerBase::reset_() { d_final = Final{ FinalData{s_unavailable, 0}, FinalData {s_unavailable, 0} }; d_state = 0; d_return = true; if (!d_more) d_matched.clear(); d_more = false; } int Scanner::executeAction_(size_t ruleIdx) try { switch (ruleIdx) { // $insert actions case 0: { #line 9 "lexer" return Parser::TXT; } break; case 1: case 2: { #line 12 "lexer" { d_verb = true; return Parser::VERB; } } break; case 3: { #line 17 "lexer" return Parser::TXT; } break; case 4: { #line 19 "lexer" return Parser::WS; } break; case 5: { #line 21 "lexer" return d_verb ? matched().front() : Parser::TXT; } break; case 6: { #line 23 "lexer" return Parser::TXT; } break; } noReturn_(); return 0; } catch (Leave_ value) { return static_cast(value); } int Scanner::lex_() { reset_(); preCode(); while (true) { size_t ch = get_(); // fetch next char size_t range = getRange_(ch); // determine the range updateFinals_(); // update the state's Final info switch (actionType_(range)) // determine the action { case ActionType_::CONTINUE: continue_(ch); continue; case ActionType_::MATCH: { d_token_ = executeAction_(matched_(ch)); if (return_()) { print(); postCode(PostEnum_::RETURN); return d_token_; } break; } case ActionType_::ECHO_FIRST: echoFirst_(ch); break; case ActionType_::ECHO_CH: echoCh_(ch); break; case ActionType_::RETURN: if (!popStream()) { postCode(PostEnum_::END); return 0; } postCode(PostEnum_::POP); continue; } // switch postCode(PostEnum_::WIP); reset_(); preCode(); } // while } void ScannerBase::print_() const { } c++-annotations-12.5.0/src/verb/scanner/scanner.ih0000644000175000017500000000037714466730207020637 0ustar frankfrank// Declare here // what's only used in the Scanner class // and let Scanner's sources include "scanner.ih" #include "scanner.h" #include "../parser/parserbase.h" // end of scanner.ih c++-annotations-12.5.0/src/verb/scanner/scanner.h0000644000175000017500000000316214466730207020461 0ustar frankfrank// Generated by Flexc++ V2.07.06 on Thu, 07 Nov 2019 22:48:49 +0530 #ifndef Scanner_H_INCLUDED_ #define Scanner_H_INCLUDED_ // $insert baseclass_h #include "scannerbase.h" // $insert classHead class Scanner: public ScannerBase { bool d_verb = false; public: explicit Scanner(std::istream &in = std::cin, std::ostream &out = std::cout); Scanner(std::string const &infile, std::string const &outfile); // $insert lexFunctionDecl int lex(); void verbEnds(); private: int lex_(); int executeAction_(size_t ruleNr); void print(); void preCode(); // re-implement this function for code that must // be exec'ed before the patternmatching starts void postCode(PostEnum_ type); // re-implement this function for code that must // be exec'ed after the rules's actions. }; inline void Scanner::verbEnds() { d_verb = false; } // $insert scannerConstructors inline Scanner::Scanner(std::istream &in, std::ostream &out) : ScannerBase(in, out) {} inline Scanner::Scanner(std::string const &infile, std::string const &outfile) : ScannerBase(infile, outfile) {} // $insert inlineLexFunction inline int Scanner::lex() { return lex_(); } inline void Scanner::preCode() { // optionally replace by your own code } inline void Scanner::postCode([[maybe_unused]] PostEnum_ type) { // optionally replace by your own code } inline void Scanner::print() { print_(); } #endif // Scanner_H_INCLUDED_ c++-annotations-12.5.0/src/verb/scanner/lexer0000644000175000017500000000101314466730207017712 0ustar frankfrank%filenames scanner %class-name "Scanner" //%interactive //%debug %% verb return Parser::TXT; "verb("[ \t]*\n | "verb(\\"\n { d_verb = true; return Parser::VERB; } [[:alnum:]]+ return Parser::TXT; [ \t\n]+ return Parser::WS; //d_verb ? Parser::WS : Parser::TXT; [()] return d_verb ? matched().front() : Parser::TXT; . return Parser::TXT; c++-annotations-12.5.0/src/verb/scanner/scannerbase.h0000644000175000017500000002726214466730207021323 0ustar frankfrank// Generated by Flexc++ V2.07.06 on Sat, 09 Nov 2019 12:08:40 +0530 #ifndef ScannerBASE_H_INCLUDED #define ScannerBASE_H_INCLUDED #include #include #include #include #include #include class ScannerBase { // idx: rule, value: tail length (NO_INCREMENTS if no tail) typedef std::vector VectorInt; static size_t const s_unavailable = std::numeric_limits::max(); enum { AT_EOF = -1 }; protected: enum Leave_ {}; enum class ActionType_ { CONTINUE, // transition succeeded, go on ECHO_CH, // echo ch itself (d_matched empty) ECHO_FIRST, // echo d_matched[0], push back the rest MATCH, // matched a rule RETURN, // no further continuation, lex returns 0. }; enum class PostEnum_ { END, // postCode called when lex_() ends POP, // postCode called after switching files RETURN, // postCode called when lex_() returns WIP // postCode called when a non-returning rule // was matched }; public: // $insert startcondenum enum class StartCondition_{ INITIAL, }; private: struct FinalData { size_t rule; size_t length; }; struct Final { FinalData std; FinalData bol; }; // class Input encapsulates all input operations. // Its member get() returns the next input character // $insert inputInterface class Input { std::deque d_deque; // pending input chars std::istream *d_in; // ptr for easy streamswitching size_t d_lineNr; // line count public: Input(); // iStream: dynamically allocated Input(std::istream *iStream, size_t lineNr = 1); size_t get(); // the next range void reRead(size_t ch); // push back 'ch' (if < 0x100) // push back str from idx 'fmIdx' void reRead(std::string const &str, size_t fmIdx); size_t lineNr() const { return d_lineNr; } size_t nPending() const { return d_deque.size(); } void setPending(size_t size) { d_deque.erase(d_deque.begin(), d_deque.end() - size); } void close() // force closing the stream { delete d_in; d_in = 0; // switchStreams also closes } private: size_t next(); // obtain the next character }; protected: struct StreamStruct { std::string pushedName; Input pushedInput; }; private: std::vector d_streamStack; std::string d_filename; // name of the currently processed static size_t s_istreamNr; // file. With istreams it receives // the name "", where // # is the sequence number of the // istream (starting at 1) int d_startCondition = 0; int d_lopSC = 0; size_t d_state = 0; int d_nextState; std::shared_ptr d_out; bool d_atBOL = true; // the matched text starts at BOL Final d_final; // only used interactively: std::istream *d_in; // points to the input stream std::shared_ptr d_line; // holds line fm d_in Input d_input; std::string d_matched; // matched characters std::string d_lopMatched; // matched lop-rule characters std::string::iterator d_lopIter; std::string::iterator d_lopTail; std::string::iterator d_lopEnd; size_t d_lopPending; // # pending input chars at lop1_ bool d_return; // return after a rule's action bool d_more = false; // set to true by more() size_t (ScannerBase::*d_get)() = &ScannerBase::getInput; protected: std::istream *d_in_; int d_token_; // returned by lex_ int const (*d_dfaBase_)[28]; static int const s_dfa_[][28]; static int const (*s_dfaBase_[])[28]; enum: bool { s_interactive_ = false }; enum: size_t { s_rangeOfEOF_ = 25, s_finIdx_ = 26, s_nRules_ = 7, s_maxSizeofStreamStack_ = 10 }; static size_t const s_ranges_[]; static size_t const s_rf_[][2]; public: ScannerBase(ScannerBase const &other) = delete; ScannerBase &operator=(ScannerBase const &rhs) = delete; bool debug() const; std::string const &filename() const; std::string const &matched() const; size_t length() const; size_t lineNr() const; void setDebug(bool onOff); void switchOstream(std::ostream &out); void switchOstream(std::string const &outfilename); void switchStreams(std::istream &in, std::ostream &out = std::cout); void switchIstream(std::string const &infilename); void switchStreams(std::string const &infilename, std::string const &outfilename); // $insert interactiveDecl protected: ScannerBase(std::istream &in, std::ostream &out); ScannerBase(std::string const &infilename, std::string const &outfilename); ~ScannerBase(); bool popStream(); std::ostream &out(); void echo() const; void leave(int retValue) const; // `accept(n)' returns all but the first `n' characters of the current // token back to the input stream, where they will be rescanned when the // scanner looks for the next match. // So, it matches n of the characters in the input buffer, and so it accepts // n characters, rescanning the rest. void accept(size_t nChars = 0); // former: less void redo(size_t nChars = 0); // rescan the last nChar // characters, reducing // length() by nChars void more(); void push(size_t ch); // push char to Input void push(std::string const &txt); // same: chars std::vector const &streamStack() const; void pushStream(std::istream &curStream); void pushStream(std::string const &curName); void setFilename(std::string const &name); void setMatched(std::string const &text); static std::string istreamName_(); // members used by lex_(): they end in _ and should not be used // otherwise. ActionType_ actionType_(size_t range); // next action bool return_(); // 'return' from codeblock size_t matched_(size_t ch); // handles a matched rule size_t getRange_(int ch); // convert char to range size_t get_(); // next character size_t state_() const; // current state void continue_(int ch); // handles a transition void echoCh_(size_t ch); // echoes ch, sets d_atBOL void echoFirst_(size_t ch); // handles unknown input void updateFinals_(); // update a state's Final info void noReturn_(); // d_return to false void print_() const; // optionally print token void pushFront_(size_t ch); // return char to Input void reset_(); // prepare for new cycle // next input stream: void switchStream_(std::istream &in, size_t lineNr); void lopf_(size_t tail); // matched fixed size tail void lop1_(int lopSC); // matched ab for a/b void lop2_(); // matches the LOP's b tail void lop3_(); // catch-all while matching b void lop4_(); // matches the LOP's a head // $insert startconddecl StartCondition_ startCondition() const; // current start condition void begin(StartCondition_ startCondition); private: static StartCondition_ constexpr SC(int sc); static int constexpr SC(StartCondition_ sc); size_t getInput(); size_t getLOP(); void p_pushStream(std::string const &name, std::istream *streamPtr); void setMatchedSize(size_t length); bool knownFinalState(); template static ReturnType constexpr as(ArgType value); static bool constexpr available(size_t value); }; inline ScannerBase::~ScannerBase() { d_input.close(); } template inline ReturnType constexpr ScannerBase::as(ArgType value) { return static_cast(value); } // $insert startcondimpl inline ScannerBase::StartCondition_ constexpr ScannerBase::SC(int sc) { return as(sc); } inline int constexpr ScannerBase::SC(StartCondition_ sc) { return as(sc); } inline ScannerBase::StartCondition_ ScannerBase::startCondition() const { return SC(d_startCondition); } inline void ScannerBase::begin(StartCondition_ startCondition) { // d_state is reset to 0 by reset_() d_dfaBase_ = s_dfaBase_[d_startCondition = SC(startCondition)]; } inline bool ScannerBase::knownFinalState() { return (d_atBOL && available(d_final.bol.rule)) || available(d_final.std.rule); } inline bool constexpr ScannerBase::available(size_t value) { return value != std::numeric_limits::max(); } inline std::ostream &ScannerBase::out() { return *d_out; } inline void ScannerBase::push(size_t ch) { d_input.reRead(ch); } inline void ScannerBase::push(std::string const &str) { d_input.reRead(str, 0); } inline void ScannerBase::setFilename(std::string const &name) { d_filename = name; } inline void ScannerBase::setMatched(std::string const &text) { d_matched = text; } inline std::string const &ScannerBase::matched() const { return d_matched; } inline std::string const &ScannerBase::filename() const { return d_filename; } inline void ScannerBase::echo() const { *d_out << d_matched; } inline size_t ScannerBase::length() const { return d_matched.size(); } inline void ScannerBase::leave(int retValue) const { throw as(retValue); } inline size_t ScannerBase::lineNr() const { return d_input.lineNr(); } inline void ScannerBase::more() { d_more = true; } inline size_t ScannerBase::state_() const { return d_state; } inline size_t ScannerBase::get_() { return (this->*d_get)(); } inline size_t ScannerBase::getInput() { return d_input.get(); } inline bool ScannerBase::return_() { return d_return; } inline void ScannerBase::noReturn_() { d_return = false; } #endif // ScannerBASE_H_INCLUDED c++-annotations-12.5.0/src/verb/VERSION0000644000175000017500000000014714466730207016276 0ustar frankfrank#define AUTHOR "Frank B. Brokken (f.b.brokken@rug.nl)"; #define VERSION "0.01.0" #define YEARS "2019" c++-annotations-12.5.0/src/verb/xerr.ih0000644000175000017500000000131314466730207016524 0ustar frankfrank// define X to activate the xerr/xerr2 macros: // xerr(insertion) // inserts the '<<' concatenated elements into std::cerr // preceded by the name of the source file, and ended by '\n' // xerr2(insertion, code) // performs the insertion if X is defined, and (unconditionally) // executes the statement(s) in `code'. `code' must be valid // C(++) code. // #ifdef XERR #include #define xerr(insertion) std::cerr << __FILE__": " << insertion << '\n' #define xerr2(insertion, b) \ { std::cerr << __FILE__": " << insertion << '\n'; b; } #else #define xerr(insertion) #define xerr2(insertion, b) b #endif c++-annotations-12.5.0/src/verb/icmconf0000644000175000017500000000210714466730207016565 0ustar frankfrank#define CLS //#define LIBRARY "modules" #define MAIN "main.cc" #define SOURCES "*.cc" #define OBJ_EXT ".o" #define TMP_DIR "tmp" //#define USE_ALL "a" #define USE_ECHO ON #define USE_VERSION #define CXX "g++" #define CXXFLAGS " --std=c++20 -Wall -O2" \ " -fdiagnostics-color=never " #define IH ".ih" //#define PRECOMP "-x c++-header" #define REFRESH #define LDFLAGS "-s" #define ADD_LIBRARIES "bobcat" #define ADD_LIBRARY_PATHS "" #define PARSER_DIR "parser" #define PARSGEN "bisonc++" #define PARSFLAGS "-V" #define PARSSPEC "grammar" #define PARSFILES "rules/*" #define PARSOUT "parse.cc" #define SCANNER_DIR "scanner" #define SCANGEN "flexc++" #define SCANFLAGS "" #define SCANSPEC "lexer" //#define SCANFILES "" #define SCANOUT "lex.cc" #define DEFCOM "program" c++-annotations-12.5.0/src/verb/main.cc0000644000175000017500000000122314466730207016455 0ustar frankfrank//#define XERR #include "main.ih" namespace { Arg::LongOption longOpts[] = { Arg::LongOption{"help", 'h'}, Arg::LongOption{"replace", 'r'}, Arg::LongOption{"version", 'v'}, }; auto longEnd = longOpts + size(longOpts); } int main(int argc, char **argv) try { Arg const &arg = Arg::initialize("hrv", longOpts, longEnd, argc, argv); arg.versionHelp(usage, Icmbuild::version, 1); Compactor compactor; compactor.run(); } catch (int value) { return Arg::instance().option("hv") ? 0 : value; } catch (exception const &exc) { cout << exc.what() << '\n'; return 1; } catch (...) { return 1; } c++-annotations-12.5.0/src/verb/version.cc0000644000175000017500000000056314466730207017224 0ustar frankfrank// version.cc #include "main.ih" #include "icmconf" #ifdef USE_VERSION #include "VERSION" #endif #ifndef AUTHOR #define AUTHOR "" #endif #ifndef VERSION #define VERSION "0.00.00" #endif #ifndef YEARS #define YEARS "2012" #endif namespace Icmbuild { char version[] = VERSION; char years[] = YEARS; char author[] = AUTHOR; } c++-annotations-12.5.0/src/verb/main.ih0000644000175000017500000000050314466730207016470 0ustar frankfrank#include #include #include #include #include "xerr.ih" #include "compactor/compactor.h" namespace Icmbuild { extern char version[]; extern char years[]; extern char author[]; }; void usage(std::string const &progname); using namespace std; using namespace FBB; c++-annotations-12.5.0/src/verb/CLASSES0000644000175000017500000000002014466730207016234 0ustar frankfrankcompactor files c++-annotations-12.5.0/src/verbnrs.cc0000644000175000017500000000325414466730207016262 0ustar frankfrank#include #include #include #include using namespace std; // first argument: file to process, 2nd argument (optional): indentation (by // default 1, which is also the minimum indentation that is used.) int main(int argc, char **argv) { string line; bool empty = true; ifstream in(argv[1]); while (getline(in, line)) // find the first non-empty line { if (line.find_first_not_of(" \t") != string::npos) // non-empty line { empty = false; // avoid doubly checking `line' break; } } if (empty) // nothing but emptyness... return 0; size_t indent = 0; if (argc > 2) indent = stoul(argv[2]); size_t lineNr = 0; size_t nEmpty = 0; // counts empty lines cout << "\n" "verb(" << setw(indent) << ' ' << setw(2) << ++lineNr << ' ' << line; // show the 1st line while (getline(in, line)) // read the rest of the file { if (line.find_first_not_of(" \t") == string::npos) // empty line { ++nEmpty; // count it continue; // proceed with the next line } if (lineNr != 0) cout << '\n'; for (size_t nr = 0; nr != nEmpty; ++nr) // 'for': # iterations known cout << setw(indent) << ' ' << setw(2) << ++lineNr << '\n'; nEmpty = 0; // reset the counter cout << setw(indent) << ' ' << setw(2) << ++lineNr << ' ' << line; // show the line } cout << ")\n"; } c++-annotations-12.5.0/src/trim/0000755000175000017500000000000014466730207015241 5ustar frankfrankc++-annotations-12.5.0/src/trim/trim.cc0000644000175000017500000000573014466730207016530 0ustar frankfrank#include #include #include #include #include #include #include #include #include "../../VERSION" using namespace std; bool silent; struct StringLine: public std::string {}; istream &operator>>(istream &in, StringLine &line) { return getline(in, line); } class Trimmer { ostream &d_out; public: Trimmer(ostream &out) : d_out(out) {} void operator()(string const &str) const { // find last non ws size_t idx = str.find_last_not_of(" \t"); if (idx == string::npos) // no non-ws char: print empty line d_out << '\n'; else if (idx + 1 == str.length()) // no trailing ws d_out << str << '\n'; else // \ requires 1 space d_out << str.substr(0, idx + 1) << '\n'; } }; void trim(char const *name = 0) { ifstream in; istream *ip; vector vs; if (!name) ip = &cin; else { if (!silent) cout << "trimming `" << name << "'\n"; in.open(name); if (!in) { cout << "no such file `" << name << "': skipped.\n"; return; } ip = ∈ } copy(istream_iterator(*ip), istream_iterator(), back_inserter(vs)); vector::reverse_iterator it = find_if(vs.rbegin(), vs.rend(), [&](string const &str) { return str.find_first_not_of(" \t") != string::npos; } ); ofstream out; ostream *op; if (!name) op = &cout; else { in.close(); out.open(name); op = &out; } for_each(vs.begin(), vector::iterator(&*(it - 1)), Trimmer{ *op }); } char const info[] = R"( [-q] [file(s)] Where: -q: quiet (optional), suppress informative messages file(s): zero or more files to process: trailing blanks at the end of lines are removed. When no files are specified, the file to process is read from the redirected standard input stream. )"; char const header[] = R"( by Frank B. Brokken (f.b.brokken@rug.nl) Trailing blanks trimmer V )" VERSION R"( Copyright (c) GPL )" YEARS R"(. NO WAARANTY. Usage: )"; int main(int argc, char **argv) { if (isatty(STDIN_FILENO) and argc == 1) { string base = basename(argv[0]); cout << base << header << base << info << '\n'; return 0; } if (argc == 1) trim(); else { if (argc > 1) silent = string("-q") == argv[1]; for (size_t idx = 1 + silent; idx != size_t(argc); ++idx) trim(argv[idx]); } } c++-annotations-12.5.0/src/rmindexlines/0000755000175000017500000000000014466730207016767 5ustar frankfrankc++-annotations-12.5.0/src/rmindexlines/rmindexlines.cc0000644000175000017500000000110114466730207021770 0ustar frankfrank#include #include using namespace std; int main() { string line1; string line2; getline(cin, line1); // initialization: pick up line 1 // which is never a \n while (getline(cin, line2)) { cout << line1; if (line2.find(" #include #include #include using namespace std; namespace fs = filesystem; //using namespace FBB; namespace { void latexMod(string const &filename) // called from tmp/docs/latex { fs::copy_file("../../../celeb/celeb30.eps", "celeb30.eps", fs::copy_options::skip_existing); ifstream latex{ filename }; // available .latex file ofstream mod{ filename + ".mod" }; // modified .latex file string line; while (true) { getline(latex, line); // find the \maketitle line if (line.find("ISBN") != string::npos) // stop at the ISBN line break; mod << line << '\n'; } ifstream table{ "../../../celeb/celeb30.latex" }; table.ignore(1000, '\n'); // skip the 1st (comment) line mod << table.rdbuf() << latex.rdbuf(); mod.close(); fs::rename(filename + ".mod", filename); } void htmlMod(string const &filename) // called from tmp/docs/html { fs::copy_file("../../../celeb/celeb30.gif", "celeb30.gif", fs::copy_options::skip_existing); ifstream html{ filename }; // available .html file ofstream mod{ filename + ".mod" }; // modified .html file string line; do { getline(html, line); // find the line mod << line << '\n'; } while (line.find("") == string::npos); // stop after ifstream table{ "../../../celeb/celeb30.html" }; table.ignore(1000, '\n'); // skip the 1st (comment) line mod << table.rdbuf() << html.rdbuf(); mod.close(); fs::rename(filename + ".mod", filename); } } int main(int argc, char **argv) { string arg{ argv[1] }; // arg[1] ends in html or latex called from tmp/docs/latex if (arg.find(".latex") != string::npos) latexMod(arg); else htmlMod(arg); } c++-annotations-12.5.0/src/keywordsort.cc0000644000175000017500000000446614466730207017203 0ustar frankfrank// use -lbobcat to link #include #include #include #include #include #include #include #include #include using namespace std; using namespace FBB; /* "alignas " "alignof and compl explicit new requires typedef and_eq concept extern not " "bool delete if private switch void break do inline protected template " "volatile " "case double int public this wchar_t catch dynamic_cast long register throw " "decltype friend or static_cast using bitor default goto or_eq struct " "virtual " "nullptr sizeof union axiom continue for operator static unsigned bitand " "short typeid asm const false not_eq signed typename auto const_cast float " "try xor_eq constexpr import export " "while char else mutable reinterpret_cast true xor class enum namespace " "char16_t char32_t noexcept static_assert thread_local " "return" ; */ // http://en.cppreference.com/w/cpp/keyword string keywords = R"( alignas alignof and and_eq asm atomic_cancel atomic_commit atomic_noexcept auto bitand bitor bool break case catch char char16_t char32_t class compl concept const constexpr const_cast continue co_await co_return co_yield decltype default delete do double dynamic_cast else enum explicit export extern false float for friend goto if import inline int long module mutable namespace new noexcept not not_eq nullptr operator or or_eq private protected public register reinterpret_cast requires return short signed sizeof static static_assert static_cast struct switch synchronized template this thread_local throw true try typedef typeid typename union unsigned using virtual void volatile wchar_t while xor xor_eq )"; struct Support: public TableSupport { void vline(size_t col) const { if (col > 0) out() << ' '; } }; int main() { set keyword; istringstream in(keywords); copy(istream_iterator(in), istream_iterator(), inserter(keyword, keyword.begin())); Support support; support << 0; for (size_t col = 0; col != 6; ++col) support << 1; Table table(support, 6, Table::COLUMNWISE); table.fill(keyword.begin(), keyword.end()); for(size_t col = 0; col != 6; ++col) table << Align(col, std::left); cout << table << '\n'; } c++-annotations-12.5.0/src/tabs/0000755000175000017500000000000014466730207015217 5ustar frankfrankc++-annotations-12.5.0/src/tabs/normalfile.cc0000644000175000017500000000040714466730207017657 0ustar frankfrank#include "main.ih" bool normalFile(char const *fileName) { struct stat fileInfo; if (lstat(fileName, &fileInfo)) { cout << "Can't stat `" << fileName << "': skipping\n"; return false; } return S_ISREG(fileInfo.st_mode); } c++-annotations-12.5.0/src/tabs/data.cc0000644000175000017500000000016014466730207016434 0ustar frankfrank#include "main.ih" bool g_entab = false; bool g_quiet = false; size_t g_minSpaces = 4; size_t g_tabWidth = 8; c++-annotations-12.5.0/src/tabs/arguments.cc0000644000175000017500000000140014466730207017526 0ustar frankfrank#include "main.ih" bool arguments(int argc, char **argv) { if (argc == 1) { string progname(argv[0]); size_t pos = progname.find_last_of('/'); if (pos != string::npos) progname.erase(0, pos + 1); usage(progname); return false; } while (true) { switch (getopt(argc, argv, "c:des:q")) { case 'e': g_entab = true; break; case 's': g_minSpaces = stoul(optarg); break; case 'c': g_tabWidth = stoul(optarg); break; case 'q': g_quiet = true; break; default: return true; } } } c++-annotations-12.5.0/src/tabs/usage.cc0000644000175000017500000000212614466730207016633 0ustar frankfrank// usage.cc #include "main.ih" void usage(std::string const &progname) { cout << '\n' << progname << " by " << Icmbuild::author << "\n" << progname << " V" << Icmbuild::version << " " << Icmbuild::years << "\n" "Copyright (c) GPL " << Icmbuild::years << ". All rights reserved.\n" "\n" "Usage: %s [-d | -e | -snnn | -cnnn]* file(s)\n" "Where:\n" " -c - entab at / detab to multiples of nnn columns " "(default: 8)\n" " -d - tabs in file(s) are removed (detab)\n" " (default action)\n" " -e - spaces in file(s) are changed into tabs (entab)\n" " -q - quiet: less output than otherwise\n" " -s - entab/detab a minimum number of nnn spaces " "(default: 4)\n" " file(s) - file(s) to entab/detab (are overwritten)\n" " use - to filter stdin to stdout\n" " non-regular files (e.g. symbolic links) are " "skipped.\n" "\n"; } c++-annotations-12.5.0/src/tabs/tabber/0000755000175000017500000000000014466730207016456 5ustar frankfrankc++-annotations-12.5.0/src/tabs/tabber/incColumn.cc0000644000175000017500000000013414466730207020712 0ustar frankfrank#include "tabber.ih" bool Tabber::tabColumn() { return ++d_column % g_tabWidth == 0; } c++-annotations-12.5.0/src/tabs/tabber/space.cc0000644000175000017500000000102514466730207020056 0ustar frankfrank#include "tabber.ih" void Tabber::space() { ++d_nSpaces; if (d_column % g_tabWidth != 0) // not at a tab-position return; if (d_nSpaces < g_minSpaces) // to few spaces to write a tab { d_out << setw(d_nSpaces) << ' '; // write blanks up to the tab-pos d_nSpaces = 0; } else // enough spaces to write a tab { d_nSpaces -= g_minSpaces; // remove #spaces converted to \t d_out.put('\t'); } } c++-annotations-12.5.0/src/tabs/tabber/tabber1.cc0000644000175000017500000000013314466730207020302 0ustar frankfrank#include "tabber.ih" Tabber::Tabber() : d_in(cin.rdbuf()), d_out(cout.rdbuf()) {} c++-annotations-12.5.0/src/tabs/tabber/run.cc0000644000175000017500000000017414466730207017573 0ustar frankfrank#include "tabber.ih" void Tabber::run() { d_column = 0; if (g_entab) entab(); else detab(); } c++-annotations-12.5.0/src/tabs/tabber/run2.cc0000644000175000017500000000031714466730207017654 0ustar frankfrank#include "tabber.ih" void Tabber::run(char const *inName, char const *outName) { ifstream in(inName); ofstream out(outName); d_in.rdbuf(in.rdbuf()); d_out.rdbuf(out.rdbuf()); run(); } c++-annotations-12.5.0/src/tabs/tabber/detab.cc0000644000175000017500000000154414466730207020050 0ustar frankfrank#include "tabber.ih" // d_column is the # of characters so far in the actual field of g_tabWidth // characters. void Tabber::detab() { char ch; while (d_in.get(ch)) { switch (ch) { case '\n': d_column = 0; // no characters in the current field, // since after this we're on the next line break; case '\t': d_out << setw(g_tabWidth - d_column) << ' '; d_column = 0; // no chars in the current field, as we // just filled it up by blanks continue; // process the next character default: d_column = (d_column + 1) % g_tabWidth; break; } d_out.put(ch); // write ordinary char. } } c++-annotations-12.5.0/src/tabs/tabber/tabber.ih0000644000175000017500000000017714466730207020244 0ustar frankfrank#include "tabber.h" #include #include #include #include "../globals.h" using namespace std; c++-annotations-12.5.0/src/tabs/tabber/entab.cc0000644000175000017500000000152614466730207020062 0ustar frankfrank#include "tabber.ih" void Tabber::entab() { char ch; while (d_in.get(ch)) { switch (ch) { case ' ': ++d_nSpaces; // got a space if (tabColumn()) // we're at a tab column { if (d_nSpaces < g_minSpaces) outSpaces(); else { d_nSpaces = 0; d_out.put('\t'); } } break; case '\n': case '\t': outSpaces(); d_out.put(ch); d_column = 0; break; default: outSpaces(); d_out.put(ch); ++d_column; break; } } } c++-annotations-12.5.0/src/tabs/tabber/tab.cc0000644000175000017500000000005514466730207017533 0ustar frankfrank#include "tabber.ih" void Tabber::tab() { } c++-annotations-12.5.0/src/tabs/tabber/outspaces.cc0000644000175000017500000000020714466730207020772 0ustar frankfrank#include "tabber.ih" void Tabber::outSpaces() { if (d_nSpaces != 0) d_out << setw(d_nSpaces) << ' '; d_nSpaces = 0; } c++-annotations-12.5.0/src/tabs/tabber/tabber.h0000644000175000017500000000075414466730207020074 0ustar frankfrank#ifndef INCLUDED_TABBER_ #define INCLUDED_TABBER_ #include #include class Tabber { std::istream d_in; std::ostream d_out; size_t d_nSpaces = 0; size_t d_column = 0; public: Tabber(); void run(); void run(char const *inName, char const *outName); private: void detab(); void entab(); bool tabColumn(); void outSpaces(); void space(); void tab(); }; #endif c++-annotations-12.5.0/src/tabs/VERSION0000644000175000017500000000015314466730207016266 0ustar frankfrank#define AUTHOR "Frank B. Brokken (f.b.brokken@rug.nl)" #define VERSION "2.00.00" #define YEARS "1999-2014" c++-annotations-12.5.0/src/tabs/icmconf0000644000175000017500000000161414466730207016562 0ustar frankfrank#define ADD_LIBRARIES "" #define ADD_LIBRARY_PATHS "" //#define CLS #define CXX "g++" #define CXXFLAGS " --std=c++0x -Wall -g -O2" //#define CFLAGS " -Wall -g -O2" #define LDFLAGS "" //#define LIBRARY "modules" #define MAIN "main.cc" #define OBJ_EXT ".o" #define PARSER_DIR "" //#define PARSFILES "" #define PARSFLAGS "" #define PARSGEN "" #define PARSOUT "" #define PARSSPEC "" //#define REFRESH #define SCANNER_DIR "" //#define SCANFILES "" #define SCANFLAGS "" #define SCANGEN "" #define SCANOUT "" #define SCANSPEC "" #define SHAREDREQ "" #define SOURCES "*.cc" #define TMP_DIR "tmp" #define USE_ECHO ON #define USE_VERSION #define DEFCOM "program" c++-annotations-12.5.0/src/tabs/main.cc0000644000175000017500000000046414466730207016456 0ustar frankfrank#include "main.ih" int main(int argc, char **argv) try { if (not arguments(argc, argv)) return 0; argv += optind; argc -= optind; Tabber tabber; if (argv[0][0] == '-') tabber.run(); if (not process(argv, tabber)) return 1; } catch (...) { return 1; } c++-annotations-12.5.0/src/tabs/version.cc0000644000175000017500000000056314466730207017217 0ustar frankfrank// version.cc #include "main.ih" #include "icmconf" #ifdef USE_VERSION #include "VERSION" #endif #ifndef AUTHOR #define AUTHOR "" #endif #ifndef VERSION #define VERSION "0.00.00" #endif #ifndef YEARS #define YEARS "2012" #endif namespace Icmbuild { char version[] = VERSION; char years[] = YEARS; char author[] = AUTHOR; } c++-annotations-12.5.0/src/tabs/process.cc0000644000175000017500000000101514466730207017201 0ustar frankfrank#include "main.ih" bool process(char **argv, Tabber &tabber) { char tempfile[] = "tab.tmp"; for (; *argv; ++argv) { if (not normalFile(*argv)) continue; if (!g_quiet) cout << "processing `" << *argv << "'\n"; unlink(tempfile); if (rename(*argv, tempfile)) { cout << "can't rename `" << *argv << "'\n"; return false; } tabber.run(tempfile, *argv); } unlink(tempfile); return true; } c++-annotations-12.5.0/src/tabs/main.ih0000644000175000017500000000071514466730207016470 0ustar frankfrank#include #include #include #include #include #include #include "globals.h" #include "tabber/tabber.h" namespace Icmbuild { extern char version[]; extern char years[]; extern char author[]; }; bool arguments(int argc, char **argv); void usage(std::string const &progname); bool normalFile(char const *fileName); bool process(char **argv, Tabber &tabber); using namespace std; c++-annotations-12.5.0/src/tabs/globals.h0000644000175000017500000000026514466730207017016 0ustar frankfrank#ifndef INCLUDED_GLOBALS_H_ #define INCLUDED_GLOBALS_H_ #include extern size_t g_minSpaces; extern size_t g_tabWidth; extern bool g_entab; extern bool g_quiet; #endif c++-annotations-12.5.0/src/tabs/CLASSES0000644000175000017500000000000714466730207016234 0ustar frankfranktabber c++-annotations-12.5.0/src/paren/0000755000175000017500000000000014466730207015373 5ustar frankfrankc++-annotations-12.5.0/src/paren/paren.cc0000644000175000017500000000516214466730207017013 0ustar frankfrank// paren.cc #include #include #include #include #include #include using namespace std; using namespace FBB; bool hdr = false; bool verbose; string version("2.00"); string years("1999-2006"); void header(char const *fn) { if (hdr) return; hdr = true; if (verbose) cout << "PROCESSING " << fn << endl; } void usage(string const &prog) { cout << "\n" << prog << " by Frank B. Brokken (f.b.brokken@rug.nl)\n" "Copyright " << years << " (c) GPL, V " << version << ".\n" "\n" "Usage: " << prog << " [-v] file(s)\n" "Where:\n" " -h: print this help-info\n" " -q: quiet: less output than otherwise\n" " -v: show the version\n" " file(s): file(s) to check for unbalanced parentheses.\n" " (A simple algorithm is used, in which all \n" " characters are treated equal).\n" "\n"; } int main(int argc, char **argv) try { Arg &arg = Arg::initialize("hqv", argc, argv); arg.versionHelp(usage, version.c_str(), 1); verbose = !arg.option('q'); bool ok = true; for (size_t idx = arg.nArgs(); idx--; ) { ifstream in(arg[idx]); if (!in) { cout << "Can't read " << arg[idx] << endl; ok = false; continue; } hdr = false; stack linenr; unsigned line = 0; string text; while (getline(in, text)) { ++line; for (char ch: text) { switch (ch) { case '(': linenr.push(line); break; case ')': if (linenr.empty()) { header(arg[idx]); cout << "\tExtra closepar in line " << line << endl; ok = false; break; } linenr.pop(); break; } } } while (!linenr.empty()) { header(arg[idx]); cout << "\tUnbalanced openpar in line " << linenr.top() << endl; linenr.pop(); ok = false; } } return ok ? 0 : 1; } catch(exception const &e) { cout << e.what() << endl; return 1; } catch(...) { return 1; } c++-annotations-12.5.0/VERSION0000644000175000017500000000006514624135461014545 0ustar frankfrank#define VERSION "12.5.0" #define YEARS "1994-2024" c++-annotations-12.5.0/yo/0000755000175000000410000000000014624645624014554 5ustar frankwww-datac++-annotations-12.5.0/yo/static.yo0000644000175000017500000000127514466730207015773 0ustar frankfrankincludefile(static/intro) lsect(StaticData)(Static data) includefile(static/data) subsect(Private static data) includefile(static/private) subsect(Public static data) includefile(static/public) subsect(Initializing static const data) includefile(static/const) lsubsect(GENCONST)(Generalized constant expressions (constexpr)) includefile(static/genconst) lsubsubsect(CONSTEXPR)(Constant expression data) includefile(static/constexprdata) sect(Static member functions) includefile(static/function) lsubsect(CALLINGCONVENTION)(Calling conventions) includefile(static/calling) c++-annotations-12.5.0/yo/wip.yo0000644000175000017500000000111114466730207015270 0ustar frankfrankincludefile(preamble) mailto(Frank B. Brokken: MYEMAIL) report() () () IFDEF(latex)(latexcommand( \cleardoublepage \pagestyle{headings} \pagenumbering{arabic}))() lsect(UNIONS)(Unrestricted Unions) includefile(containers/unrestricted) subsect(Implementing the destructor) includefile(containers/uniondestructor) subsect(Embedding an unrestricted union in a surrounding class) includefile(containers/embedding) subsect(Swapping unrestricted unions) includefile(containers/unionswap) subsect(Assignment) includefile(containers/assignment) c++-annotations-12.5.0/yo/namespaces/0000755000175000017500000000000014522250255016236 5ustar frankfrankc++-annotations-12.5.0/yo/namespaces/examples/0000755000175000017500000000000014624637126020065 5ustar frankfrankc++-annotations-12.5.0/yo/namespaces/examples/koenig1.cc0000664000175000017500000000067514624637133021741 0ustar frankfrank #include namespace FBB { enum Value // defines FBB::Value { FIRST }; void fun(Value x) { std::cout << "fun called for " << x << '\n'; } } int main() { fun(FBB::FIRST); // Koenig lookup: no namespace // for fun() specified } /* generated output: fun called for 0 */ c++-annotations-12.5.0/yo/namespaces/examples/koenig3.cc0000664000175000017500000000145314624637133021736 0ustar frankfrank #include namespace ES { enum Value // defines ES::Value { FIRST }; } namespace FBB { enum Value // defines FBB::Value { FIRST }; void fun(Value x, ES::Value y) { std::cout << "FBB::fun() called\n"; } } namespace ES { void fun(FBB::Value x, Value y) { std::cout << "ES::fun() called\n"; } } int main() { // fun(FBB::FIRST, ES::FIRST); ambiguity: resolved by // explicitly mentioning // the namespace ES::fun(FBB::FIRST, ES::FIRST); } /* generated output: ES::fun() called */ c++-annotations-12.5.0/yo/namespaces/examples/nesting.cc0000664000175000017500000000156214624637133022047 0ustar frankfranknamespace CppAnnotations { int value; namespace Virtual { void *pointer; } } // // 0 //using namespace CppAnnotations; // 1 //using namespace CppAnnotations::Virtual; // 2 //using namespace CppAnnotations; // 3 //using namespace Virtual; //using CppAnnotations::value; // 4 //using CppAnnotations::Virtual::pointer; //using namespace CppAnnotations::Virtual; // 5 //using CppAnnotations::value; int main() { // CppAnnotations::Virtual::pointer = 0; // 0 // CppAnnotations::value = 0; // value = 0; // 1 // Virtual::pointer = 0; // CppAnnotations::value = 0; // 2 // pointer = 0; // value = 0; // 3, 4, 5 // pointer = 0; } c++-annotations-12.5.0/yo/namespaces/examples/compound.cc0000664000175000017500000000044614624637133022224 0ustar frankfrank#include #include struct Namespace { // using namespace std; cannot be used here std::string d_str; std::string text() const; }; int main() { using namespace std; // but here is OK string text; Namespace ns; cout << ns.text(); } c++-annotations-12.5.0/yo/namespaces/examples/koenig2.cc0000664000175000017500000000113314624637133021730 0ustar frankfrank #include namespace FBB { enum Value // defines FBB::Value { FIRST }; void fun(Value x) { std::cout << "FBB::fun() called for " << x << '\n'; } } namespace ES { void fun(FBB::Value x) { std::cout << "ES::fun() called for " << x << '\n'; } } int main() { fun(FBB::FIRST); // No ambiguity: argument determines // the namespace } /* generated output: FBB::fun() called for 0 */ c++-annotations-12.5.0/yo/namespaces/examples/koenig4.cc0000664000175000017500000000043114624637133021732 0ustar frankfrank namespace FBB { struct Value {}; void fun(int x); void gun(Value x); } namespace ES { void fun(int x) { fun(x); } void gun(FBB::Value x) { gun(x); } } c++-annotations-12.5.0/yo/namespaces/filesystem/0000755000175000017500000000000014624366470020434 5ustar frankfrankc++-annotations-12.5.0/yo/namespaces/filesystem/examples/0000755000175000017500000000000014624637126022251 5ustar frankfrankc++-annotations-12.5.0/yo/namespaces/filesystem/examples/fileclock.cc0000664000175000017500000001127714624637133024523 0ustar frankfrank#include #include #include using namespace std; using namespace filesystem; using namespace chrono; // 318315729 // 1403456322 -1085140593 // -1'085'344'473 class FC { struct In { tm d_tm; char const *d_fmt; In(tm const &tmData, char const *fmt); ostream &insert(ostream &out) const; }; friend ostream &operator<<(ostream &out, In const &in); using time_t2tm = tm (*)(const time_t *); using TPfileClock = time_point<__file_clock>; using TPsystemClock = time_point; static TPsystemClock const s_sPoint; static int const s_offset; public: enum TimeType { LT, GMT }; // system time point corresponding to __file_clock static TPsystemClock sysTimePoint(TPfileClock const &fp); // tm corresponding to __file_clock for local time static tm tmLocal(TPfileClock const &ftp); // tm corresponding to __file_clock for gmtime static tm tmGMT(TPfileClock const &ftp); static In put_time(TPfileClock const &fp, char const *fmt = "%c", TimeType type = LT); private: static tm to_tm(tm *(*funPtr)(const time_t *), TPfileClock const &fp); }; // static data FC::TPsystemClock const FC::s_sPoint = system_clock::now(); // 'now' expressed for file_clock int const FC::s_offset = FC::s_sPoint.time_since_epoch().count() - __file_clock::now().time_since_epoch().count(); FC::In::In(tm const &tmData, char const *fmt) : d_tm(tmData), d_fmt(fmt) {} ostream &FC::In::insert(ostream &out) const { return out << std::put_time(&d_tm, d_fmt); }; ostream &operator<<(ostream &out, FC::In const &in) { return in.insert(out); } FC::In FC::put_time(TPfileClock const &fp, char const *fmt, TimeType type) { return In{type == LT ? tmLocal(fp) : tmGMT(fp), fmt }; } // cout << fc(fPoint) << '\n'; FC::TPsystemClock FC::sysTimePoint(TPfileClock const &fp) { int fnow = fp.time_since_epoch().count(); fnow += s_offset; // time according to the system clock return s_sPoint + nanoseconds(fnow); } tm FC::tmLocal(TPfileClock const &fp) { return to_tm(gmtime, fp); } tm FC::tmGMT(TPfileClock const &fp) { return to_tm(localtime, fp); } tm FC::to_tm(tm *(*funPtr)(const time_t *), TPfileClock const &fp) { time_t secs = system_clock::to_time_t( sysTimePoint(fp) + nanoseconds{ s_offset } ); return *(*funPtr)(&secs); } time_point conv1(time_point<__file_clock> const &point) { auto systemNow = system_clock::now().time_since_epoch(); auto fileNow = __file_clock::now().time_since_epoch(); return time_point{ nanoseconds(point.time_since_epoch() + systemNow - fileNow) }; } int main() { // 'now' expressed for system_clock time_point sPoint = system_clock::now(); int snow = sPoint.time_since_epoch().count(); cout << "system now in seconds since the epoch: " << snow << '\n'; // current local time time_t secs = system_clock::to_time_t(sPoint); cout << put_time(localtime(&secs), "%c") << '\n'; // 'now' expressed for file_clock time_point<__file_clock> fPoint = __file_clock::now(); int fnow = fPoint.time_since_epoch().count(); cout << "file clock now in seconds since the (fc) epoch: " << fnow << '\n'; int offset = snow - fnow; // difference between system- and fileclock cout << snow << ' ' << fnow << ' ' << offset << '\n'; time_point epoch; secs = system_clock::to_time_t(epoch); cout << "begin of system epoch: secs = " << secs << ", time: " << put_time(gmtime(&secs), "%c") << '\n'; time_point epochFC{ nanoseconds(-100'000'000'000) }; secs = system_clock::to_time_t(epochFC); cout << "begin of _file_clock epoch: seconds: " << secs << ", time: " << put_time(gmtime(&secs), "%c") << '\n'; // to go from filesystem_clock to system_clock add offset (expressed in // nanoseconds) to the int-count obtained from the filesystem_clock's // time_point. sPoint += nanoseconds{ offset }; secs = system_clock::to_time_t(sPoint); cout << put_time(localtime(&secs), "%c") << '\n'; tm tmData{ FC::tmLocal(fPoint) }; cout << put_time(&tmData, "%c") << '\n'; cout << FC::put_time(fPoint) << '\n'; } c++-annotations-12.5.0/yo/namespaces/filesystem/examples/spaceinfo.cc0000664000175000017500000000102614624637133024526 0ustar frankfrank#include #include using namespace std; using namespace filesystem; //demo int main() { path tmp{ "/tmp" }; auto pod = space(tmp); cout << "The filesystem containing /tmp has a capacity of " << pod.capacity << " bytes,\n" "i.e., " << pod.capacity / (1024 * 1024) << " MB.\n" "# free bytes: " << pod.free << "\n" "# available: " << pod.available << "\n" "free + available: " << pod.free + pod.available << '\n'; } //= c++-annotations-12.5.0/yo/namespaces/filesystem/examples/filesystemerror.cc0000664000175000017500000000122714624637133026020 0ustar frankfrank#include #include using namespace std; using namespace filesystem; //fse int main() try { try { throw filesystem_error{ "exception encountered", "p1", "p2", make_error_code(errc::address_in_use) }; } catch (filesystem_error const &fse) { cerr << "what: " << fse.what() << "\n" "path1: " << fse.path1() << "\n" "path2: " << fse.path2() << "\n" "code: " << fse.code() << '\n'; throw; } } catch (exception const &ec) { cerr << "\n" "plain exception's what: " << ec.what() << "\n\n"; } //= c++-annotations-12.5.0/yo/namespaces/filesystem/examples/tosys.cc0000664000175000017500000000116514624637133023744 0ustar frankfrank#include #include #include using namespace std; using namespace chrono; using namespace filesystem; int main() { //system_clock::to_sys(system_clock::now()); // not for system_clock // steady_clock::to_sys(steady_clock::now()); // not for steady_clock // high_resolution_clock::to_sys( // not for high_res._clock // high_resolution_clock::now()); __file_clock::to_sys(__file_clock::now()); //__file_clock::to_time_t(__file_clock::now()); // not in __file_clock // steady_clock::to_time_t(steady_clock::now());// not in steady_clock } c++-annotations-12.5.0/yo/namespaces/filesystem/examples/lastwritetime2.cc0000664000175000017500000000064414624637133025543 0ustar frankfrank#include #include #include using namespace std; using namespace filesystem; using namespace chrono; //demo int main() { time_t seconds = system_clock::to_time_t( __file_clock::to_sys(last_write_time("lastwritetime.cc")) ); cout << "lastwritetime.cc's last (UTC) write time: " << put_time(gmtime(&seconds), "%c") << '\n'; } //= c++-annotations-12.5.0/yo/namespaces/filesystem/examples/directoryentry.cc0000664000175000017500000000053514624637133025651 0ustar frankfrank//de #include #include using namespace std; using namespace filesystem; int main(int argc, char **argv) // provide 2 arguments { directory_entry de{ argv[1] }; cout << de.path() << '\n'; de.replace_filename(argv[2]); cout << de.path() << '\n'; de.assign(argv[2]); cout << de.path() << '\n'; } //= c++-annotations-12.5.0/yo/namespaces/filesystem/examples/tosys/0000755000175000017500000000000014624637126023432 5ustar frankfrankc++-annotations-12.5.0/yo/namespaces/filesystem/examples/tosys/crono.MS0000644000175000017500000105556014466730207025025 0ustar frankfrank// chrono standard header #pragma once #ifndef _CHRONO_ #define _CHRONO_ #include #if _STL_COMPILER_PREPROCESSOR #include #include #include #include #include #include #if _HAS_CXX20 #include <__msvc_tzdb.hpp> #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __cpp_lib_concepts #include #endif // defined(__cpp_lib_concepts) #ifdef __cpp_lib_format #include #include #endif // defined(__cpp_lib_format) #endif // _HAS_CXX20 #pragma pack(push, _CRT_PACKING) #pragma warning(push, _STL_WARNING_LEVEL) #pragma warning(disable : _STL_DISABLED_WARNINGS) _STL_DISABLE_CLANG_WARNINGS #pragma push_macro("new") #undef new _STD_BEGIN namespace chrono { template struct treat_as_floating_point : is_floating_point<_Rep> {}; // tests for floating-point type template _INLINE_VAR constexpr bool treat_as_floating_point_v = treat_as_floating_point<_Rep>::value; template struct duration_values { // gets arithmetic properties of a type _NODISCARD static constexpr _Rep zero() noexcept { // get zero value return _Rep(0); } _NODISCARD static constexpr _Rep(min)() noexcept { // get smallest value return numeric_limits<_Rep>::lowest(); } _NODISCARD static constexpr _Rep(max)() noexcept { // get largest value return (numeric_limits<_Rep>::max) (); } }; #if _HAS_CXX20 template inline constexpr bool _Is_clock_v = false; template inline constexpr bool _Is_clock_v<_Clock, void_t> = true; // TRANSITION, GH-602 template struct is_clock : bool_constant<_Is_clock_v<_Clock>> {}; template inline constexpr bool is_clock_v = _Is_clock_v<_Clock>; #endif // _HAS_CXX20 template > class duration; template _INLINE_VAR constexpr bool _Is_duration_v = _Is_specialization_v<_Ty, duration>; template , int> = 0> constexpr _To duration_cast(const duration<_Rep, _Period>&) noexcept( is_arithmetic_v<_Rep>&& is_arithmetic_v); // strengthened template class duration { // represents a time duration public: using rep = _Rep; using period = typename _Period::type; static_assert(!_Is_duration_v<_Rep>, "duration can't have duration as first template argument"); static_assert(_Is_ratio_v<_Period>, "period not an instance of std::ratio"); static_assert(0 < _Period::num, "period negative or zero"); constexpr duration() = default; template && (treat_as_floating_point_v<_Rep> || !treat_as_floating_point_v<_Rep2>), int> = 0> constexpr explicit duration(const _Rep2& _Val) noexcept( is_arithmetic_v<_Rep>&& is_arithmetic_v<_Rep2>) // strengthened : _MyRep(static_cast<_Rep>(_Val)) {} template || (_Ratio_divide_sfinae<_Period2, _Period>::den == 1 && !treat_as_floating_point_v<_Rep2>), int> = 0> constexpr duration(const duration<_Rep2, _Period2>& _Dur) noexcept( is_arithmetic_v<_Rep>&& is_arithmetic_v<_Rep2>) // strengthened : _MyRep(_CHRONO duration_cast(_Dur).count()) {} _NODISCARD constexpr _Rep count() const noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { return _MyRep; } _NODISCARD constexpr common_type_t operator+() const noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { return common_type_t(*this); } _NODISCARD constexpr common_type_t operator-() const noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { return common_type_t(-_MyRep); } _CONSTEXPR17 duration& operator++() noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { ++_MyRep; return *this; } _CONSTEXPR17 duration operator++(int) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { return duration(_MyRep++); } _CONSTEXPR17 duration& operator--() noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { --_MyRep; return *this; } _CONSTEXPR17 duration operator--(int) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { return duration(_MyRep--); } _CONSTEXPR17 duration& operator+=(const duration& _Right) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { _MyRep += _Right._MyRep; return *this; } _CONSTEXPR17 duration& operator-=(const duration& _Right) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { _MyRep -= _Right._MyRep; return *this; } _CONSTEXPR17 duration& operator*=(const _Rep& _Right) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { _MyRep *= _Right; return *this; } _CONSTEXPR17 duration& operator/=(const _Rep& _Right) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { _MyRep /= _Right; return *this; } _CONSTEXPR17 duration& operator%=(const _Rep& _Right) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { _MyRep %= _Right; return *this; } _CONSTEXPR17 duration& operator%=(const duration& _Right) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { _MyRep %= _Right.count(); return *this; } _NODISCARD static constexpr duration zero() noexcept { // get zero value return duration(duration_values<_Rep>::zero()); } _NODISCARD static constexpr duration(min)() noexcept { // get minimum value return duration((duration_values<_Rep>::min) ()); } _NODISCARD static constexpr duration(max)() noexcept { // get maximum value return duration((duration_values<_Rep>::max) ()); } private: _Rep _MyRep; // the stored rep }; template class time_point { // represents a point in time public: using clock = _Clock; using duration = _Duration; using rep = typename _Duration::rep; using period = typename _Duration::period; static_assert(_Is_duration_v<_Duration>, "N4885 [time.point.general]/1 mandates Duration to be a specialization of chrono::duration."); constexpr time_point() = default; constexpr explicit time_point(const _Duration& _Other) noexcept(is_arithmetic_v) // strengthened : _MyDur(_Other) {} template , int> = 0> constexpr time_point(const time_point<_Clock, _Duration2>& _Tp) noexcept( is_arithmetic_v&& is_arithmetic_v) // strengthened : _MyDur(_Tp.time_since_epoch()) {} _NODISCARD constexpr _Duration time_since_epoch() const noexcept(is_arithmetic_v) /* strengthened */ { return _MyDur; } #if _HAS_CXX20 constexpr time_point& operator++() noexcept(is_arithmetic_v) /* strengthened */ { ++_MyDur; return *this; } constexpr time_point operator++(int) noexcept(is_arithmetic_v) /* strengthened */ { return time_point{_MyDur++}; } constexpr time_point& operator--() noexcept(is_arithmetic_v) /* strengthened */ { --_MyDur; return *this; } constexpr time_point operator--(int) noexcept(is_arithmetic_v) /* strengthened */ { return time_point{_MyDur--}; } #endif // _HAS_CXX20 _CONSTEXPR17 time_point& operator+=(const _Duration& _Dur) noexcept(is_arithmetic_v) /* strengthened */ { _MyDur += _Dur; return *this; } _CONSTEXPR17 time_point& operator-=(const _Duration& _Dur) noexcept(is_arithmetic_v) /* strengthened */ { _MyDur -= _Dur; return *this; } _NODISCARD static constexpr time_point(min)() noexcept { return time_point((_Duration::min) ()); } _NODISCARD static constexpr time_point(max)() noexcept { return time_point((_Duration::max) ()); } private: _Duration _MyDur{duration::zero()}; // duration since the epoch }; } // namespace chrono template _INLINE_VAR constexpr bool _Is_trivially_swappable_v> = _Is_trivially_swappable_v<_Rep>; template _INLINE_VAR constexpr bool _Is_trivially_swappable_v> = _Is_trivially_swappable_v<_Duration>; template struct _Lcm : integral_constant::value) * _Bx> {}; // compute LCM of _Ax and _Bx template struct common_type<_CHRONO duration<_Rep1, _Period1>, _CHRONO duration<_Rep2, _Period2>> { // common type of two durations using type = _CHRONO duration, ratio<_Gcd<_Period1::num, _Period2::num>::value, _Lcm<_Period1::den, _Period2::den>::value>>; }; template struct common_type<_CHRONO time_point<_Clock, _Duration1>, _CHRONO time_point<_Clock, _Duration2>> { // common type of two time points using type = _CHRONO time_point<_Clock, common_type_t<_Duration1, _Duration2>>; }; namespace chrono { template _NODISCARD constexpr common_type_t, duration<_Rep2, _Period2>> operator+(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { using _CD = common_type_t, duration<_Rep2, _Period2>>; return _CD(_CD(_Left).count() + _CD(_Right).count()); } template _NODISCARD constexpr common_type_t, duration<_Rep2, _Period2>> operator-(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { using _CD = common_type_t, duration<_Rep2, _Period2>>; return _CD(_CD(_Left).count() - _CD(_Right).count()); } template >, int> = 0> _NODISCARD constexpr duration, _Period1> operator*( const duration<_Rep1, _Period1>& _Left, const _Rep2& _Right) noexcept(is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { using _CR = common_type_t<_Rep1, _Rep2>; using _CD = duration<_CR, _Period1>; return _CD(_CD(_Left).count() * _Right); } template >, int> = 0> _NODISCARD constexpr duration, _Period2> operator*(const _Rep1& _Left, const duration<_Rep2, _Period2>& _Right) noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { return _Right * _Left; } template > struct _Duration_div_mod1 { // return type for duration / rep and duration % rep using type = duration<_CR, _Period1>; }; template struct _Duration_div_mod1<_CR, _Period1, _Rep2, false> {}; // no return type template > struct _Duration_div_mod {}; // no return type template struct _Duration_div_mod<_CR, _Period1, _Rep2, false> : _Duration_div_mod1<_CR, _Period1, _Rep2> { // return type for duration / rep and duration % rep }; template _NODISCARD constexpr typename _Duration_div_mod, _Period1, _Rep2>::type operator/( const duration<_Rep1, _Period1>& _Left, const _Rep2& _Right) noexcept(is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { using _CR = common_type_t<_Rep1, _Rep2>; using _CD = duration<_CR, _Period1>; return _CD(_CD(_Left).count() / _Right); } template _NODISCARD constexpr common_type_t<_Rep1, _Rep2> operator/(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { using _CD = common_type_t, duration<_Rep2, _Period2>>; return _CD(_Left).count() / _CD(_Right).count(); } template _NODISCARD constexpr typename _Duration_div_mod, _Period1, _Rep2>::type operator%( const duration<_Rep1, _Period1>& _Left, const _Rep2& _Right) noexcept(is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { using _CR = common_type_t<_Rep1, _Rep2>; using _CD = duration<_CR, _Period1>; return _CD(_CD(_Left).count() % _Right); } template _NODISCARD constexpr common_type_t, duration<_Rep2, _Period2>> operator%(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { using _CD = common_type_t, duration<_Rep2, _Period2>>; return _CD(_CD(_Left).count() % _CD(_Right).count()); } template _NODISCARD constexpr bool operator==(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { using _CT = common_type_t, duration<_Rep2, _Period2>>; return _CT(_Left).count() == _CT(_Right).count(); } #if !_HAS_CXX20 template _NODISCARD constexpr bool operator!=(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { return !(_Left == _Right); } #endif // !_HAS_CXX20 template _NODISCARD constexpr bool operator<(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { using _CT = common_type_t, duration<_Rep2, _Period2>>; return _CT(_Left).count() < _CT(_Right).count(); } template _NODISCARD constexpr bool operator<=(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { return !(_Right < _Left); } template _NODISCARD constexpr bool operator>(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { return _Right < _Left; } template _NODISCARD constexpr bool operator>=(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { return !(_Left < _Right); } #ifdef __cpp_lib_concepts // clang-format off template requires three_way_comparable, duration<_Rep2, _Period2>>::rep> _NODISCARD constexpr auto operator<=>(const duration<_Rep1, _Period1>& _Left, const duration<_Rep2, _Period2>& _Right) noexcept( is_arithmetic_v<_Rep1>&& is_arithmetic_v<_Rep2>) /* strengthened */ { // clang-format on using _CT = common_type_t, duration<_Rep2, _Period2>>; return _CT(_Left).count() <=> _CT(_Right).count(); } #endif // defined(__cpp_lib_concepts) template , int> _Enabled> _NODISCARD constexpr _To duration_cast(const duration<_Rep, _Period>& _Dur) noexcept( is_arithmetic_v<_Rep>&& is_arithmetic_v) /* strengthened */ { // convert duration to another duration; truncate using _CF = ratio_divide<_Period, typename _To::period>; using _ToRep = typename _To::rep; using _CR = common_type_t<_ToRep, _Rep, intmax_t>; constexpr bool _Num_is_one = _CF::num == 1; constexpr bool _Den_is_one = _CF::den == 1; if (_Den_is_one) { if (_Num_is_one) { return static_cast<_To>(static_cast<_ToRep>(_Dur.count())); } else { return static_cast<_To>( static_cast<_ToRep>(static_cast<_CR>(_Dur.count()) * static_cast<_CR>(_CF::num))); } } else { if (_Num_is_one) { return static_cast<_To>( static_cast<_ToRep>(static_cast<_CR>(_Dur.count()) / static_cast<_CR>(_CF::den))); } else { return static_cast<_To>(static_cast<_ToRep>( static_cast<_CR>(_Dur.count()) * static_cast<_CR>(_CF::num) / static_cast<_CR>(_CF::den))); } } } template , int> = 0> _NODISCARD constexpr _To floor(const duration<_Rep, _Period>& _Dur) noexcept( is_arithmetic_v<_Rep>&& is_arithmetic_v) /* strengthened */ { // convert duration to another duration; round towards negative infinity // i.e. the greatest integral result such that the result <= _Dur const _To _Casted{_CHRONO duration_cast<_To>(_Dur)}; if (_Casted > _Dur) { return _To{_Casted.count() - static_cast(1)}; } return _Casted; } template , int> = 0> _NODISCARD constexpr _To ceil(const duration<_Rep, _Period>& _Dur) noexcept( is_arithmetic_v<_Rep>&& is_arithmetic_v) /* strengthened */ { // convert duration to another duration; round towards positive infinity // i.e. the least integral result such that _Dur <= the result const _To _Casted{_CHRONO duration_cast<_To>(_Dur)}; if (_Casted < _Dur) { return _To{_Casted.count() + static_cast(1)}; } return _Casted; } template constexpr bool _Is_even(_Rep _Val) noexcept(is_arithmetic_v<_Rep>) /* strengthened */ { // Tests whether _Val is even return _Val % 2 == 0; } template && !treat_as_floating_point_v, int> = 0> _NODISCARD constexpr _To round(const duration<_Rep, _Period>& _Dur) noexcept( is_arithmetic_v<_Rep>&& is_arithmetic_v) /* strengthened */ { // convert duration to another duration, round to nearest, ties to even const _To _Floored{_CHRONO floor<_To>(_Dur)}; const _To _Ceiled{_Floored + _To{1}}; const auto _Floor_adjustment = _Dur - _Floored; const auto _Ceil_adjustment = _Ceiled - _Dur; if (_Floor_adjustment < _Ceil_adjustment || (_Floor_adjustment == _Ceil_adjustment && _Is_even(_Floored.count()))) { return _Floored; } return _Ceiled; } template ::is_signed, int> = 0> _NODISCARD constexpr duration<_Rep, _Period> abs(const duration<_Rep, _Period> _Dur) noexcept( is_arithmetic_v<_Rep>) /* strengthened */ { // create a duration with count() the absolute value of _Dur.count() return _Dur < duration<_Rep, _Period>::zero() ? duration<_Rep, _Period>::zero() - _Dur : _Dur; } using nanoseconds = duration; using microseconds = duration; using milliseconds = duration; using seconds = duration; using minutes = duration>; using hours = duration>; #if _HAS_CXX20 using days = duration, hours::period>>; using weeks = duration, days::period>>; using years = duration, days::period>>; using months = duration>>; #endif // _HAS_CXX20 template _NODISCARD constexpr time_point<_Clock, common_type_t<_Duration, duration<_Rep, _Period>>> operator+(const time_point<_Clock, _Duration>& _Left, const duration<_Rep, _Period>& _Right) noexcept( is_arithmetic_v&& is_arithmetic_v<_Rep>) /* strengthened */ { using _RT = time_point<_Clock, common_type_t<_Duration, duration<_Rep, _Period>>>; return _RT(_Left.time_since_epoch() + _Right); } template _NODISCARD constexpr time_point<_Clock, common_type_t, _Duration>> operator+(const duration<_Rep, _Period>& _Left, const time_point<_Clock, _Duration>& _Right) noexcept( is_arithmetic_v<_Rep>&& is_arithmetic_v) /* strengthened */ { return _Right + _Left; } template _NODISCARD constexpr time_point<_Clock, common_type_t<_Duration, duration<_Rep, _Period>>> operator-(const time_point<_Clock, _Duration>& _Left, const duration<_Rep, _Period>& _Right) noexcept( is_arithmetic_v&& is_arithmetic_v<_Rep>) /* strengthened */ { using _RT = time_point<_Clock, common_type_t<_Duration, duration<_Rep, _Period>>>; return _RT(_Left.time_since_epoch() - _Right); } template _NODISCARD constexpr common_type_t<_Duration1, _Duration2> operator-(const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) noexcept( is_arithmetic_v&& is_arithmetic_v) /* strengthened */ { return _Left.time_since_epoch() - _Right.time_since_epoch(); } template _NODISCARD constexpr bool operator==(const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) noexcept( is_arithmetic_v&& is_arithmetic_v) /* strengthened */ { return _Left.time_since_epoch() == _Right.time_since_epoch(); } #if !_HAS_CXX20 template _NODISCARD constexpr bool operator!=(const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) noexcept( is_arithmetic_v&& is_arithmetic_v) /* strengthened */ { return !(_Left == _Right); } #endif // !_HAS_CXX20 template _NODISCARD constexpr bool operator<(const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) noexcept( is_arithmetic_v&& is_arithmetic_v) /* strengthened */ { return _Left.time_since_epoch() < _Right.time_since_epoch(); } template _NODISCARD constexpr bool operator<=(const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) noexcept( is_arithmetic_v&& is_arithmetic_v) /* strengthened */ { return !(_Right < _Left); } template _NODISCARD constexpr bool operator>(const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) noexcept( is_arithmetic_v&& is_arithmetic_v) /* strengthened */ { return _Right < _Left; } template _NODISCARD constexpr bool operator>=(const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) noexcept( is_arithmetic_v&& is_arithmetic_v) /* strengthened */ { return !(_Left < _Right); } #ifdef __cpp_lib_concepts template _Duration2> _NODISCARD constexpr auto operator<=>(const time_point<_Clock, _Duration1>& _Left, const time_point<_Clock, _Duration2>& _Right) noexcept( is_arithmetic_v&& is_arithmetic_v) /* strengthened */ { return _Left.time_since_epoch() <=> _Right.time_since_epoch(); } #endif // defined(__cpp_lib_concepts) template , int> = 0> _NODISCARD constexpr time_point<_Clock, _To> time_point_cast(const time_point<_Clock, _Duration>& _Time) noexcept( is_arithmetic_v&& is_arithmetic_v) /* strengthened */ { // change the duration type of a time_point; truncate return time_point<_Clock, _To>(_CHRONO duration_cast<_To>(_Time.time_since_epoch())); } template , int> = 0> _NODISCARD constexpr time_point<_Clock, _To> floor(const time_point<_Clock, _Duration>& _Time) noexcept( is_arithmetic_v&& is_arithmetic_v) /* strengthened */ { // change the duration type of a time_point; round towards negative infinity return time_point<_Clock, _To>(_CHRONO floor<_To>(_Time.time_since_epoch())); } template , int> = 0> _NODISCARD constexpr time_point<_Clock, _To> ceil(const time_point<_Clock, _Duration>& _Time) noexcept( is_arithmetic_v&& is_arithmetic_v) /* strengthened */ { // change the duration type of a time_point; round towards positive infinity return time_point<_Clock, _To>(_CHRONO ceil<_To>(_Time.time_since_epoch())); } template && !treat_as_floating_point_v, int> = 0> _NODISCARD constexpr time_point<_Clock, _To> round(const time_point<_Clock, _Duration>& _Time) noexcept( is_arithmetic_v&& is_arithmetic_v) /* strengthened */ { // change the duration type of a time_point; round to nearest, ties to even return time_point<_Clock, _To>(_CHRONO round<_To>(_Time.time_since_epoch())); } struct system_clock { // wraps GetSystemTimePreciseAsFileTime/GetSystemTimeAsFileTime using rep = long long; using period = ratio<1, 10'000'000>; // 100 nanoseconds using duration = _CHRONO duration; using time_point = _CHRONO time_point; static constexpr bool is_steady = false; _NODISCARD static time_point now() noexcept { // get current time return time_point(duration(_Xtime_get_ticks())); } _NODISCARD static __time64_t to_time_t(const time_point& _Time) noexcept { // convert to __time64_t return duration_cast(_Time.time_since_epoch()).count(); } _NODISCARD static time_point from_time_t(__time64_t _Tm) noexcept { // convert from __time64_t return time_point{seconds{_Tm}}; } }; #if _HAS_CXX20 template using sys_time = time_point; using sys_seconds = sys_time; using sys_days = sys_time; #endif // _HAS_CXX20 struct steady_clock { // wraps QueryPerformanceCounter using rep = long long; using period = nano; using duration = nanoseconds; using time_point = _CHRONO time_point; static constexpr bool is_steady = true; _NODISCARD static time_point now() noexcept { // get current time const long long _Freq = _Query_perf_frequency(); // doesn't change after system boot const long long _Ctr = _Query_perf_counter(); static_assert(period::num == 1, "This assumes period::num == 1."); // Instead of just having "(_Ctr * period::den) / _Freq", // the algorithm below prevents overflow when _Ctr is sufficiently large. // It assumes that _Freq * period::den does not overflow, which is currently true for nano period. // It is not realistic for _Ctr to accumulate to large values from zero with this assumption, // but the initial value of _Ctr could be large. const long long _Whole = (_Ctr / _Freq) * period::den; const long long _Part = (_Ctr % _Freq) * period::den / _Freq; return time_point(duration(_Whole + _Part)); } }; using high_resolution_clock = steady_clock; #if _HAS_CXX20 // [time.duration.io] #define _IF_PERIOD_RETURN_SUFFIX_ELSE(_TYPE, _SUFFIX) \ if constexpr (is_same_v<_Period, _TYPE>) { \ if constexpr (is_same_v<_CharT, char>) { \ return _SUFFIX; \ } else { \ return L##_SUFFIX; \ } \ } else template _NODISCARD constexpr const _CharT* _Get_literal_unit_suffix() { _IF_PERIOD_RETURN_SUFFIX_ELSE(atto, "as") _IF_PERIOD_RETURN_SUFFIX_ELSE(femto, "fs") _IF_PERIOD_RETURN_SUFFIX_ELSE(pico, "ps") _IF_PERIOD_RETURN_SUFFIX_ELSE(nano, "ns") _IF_PERIOD_RETURN_SUFFIX_ELSE(micro, "us") _IF_PERIOD_RETURN_SUFFIX_ELSE(milli, "ms") _IF_PERIOD_RETURN_SUFFIX_ELSE(centi, "cs") _IF_PERIOD_RETURN_SUFFIX_ELSE(deci, "ds") _IF_PERIOD_RETURN_SUFFIX_ELSE(seconds::period, "s") _IF_PERIOD_RETURN_SUFFIX_ELSE(deca, "das") _IF_PERIOD_RETURN_SUFFIX_ELSE(hecto, "hs") _IF_PERIOD_RETURN_SUFFIX_ELSE(kilo, "ks") _IF_PERIOD_RETURN_SUFFIX_ELSE(mega, "Ms") _IF_PERIOD_RETURN_SUFFIX_ELSE(giga, "Gs") _IF_PERIOD_RETURN_SUFFIX_ELSE(tera, "Ts") _IF_PERIOD_RETURN_SUFFIX_ELSE(peta, "Ps") _IF_PERIOD_RETURN_SUFFIX_ELSE(exa, "Es") _IF_PERIOD_RETURN_SUFFIX_ELSE(minutes::period, "min") _IF_PERIOD_RETURN_SUFFIX_ELSE(hours::period, "h") _IF_PERIOD_RETURN_SUFFIX_ELSE(ratio<86400>, "d") { return nullptr; } } #undef _IF_PERIOD_RETURN_SUFFIX_ELSE template _NODISCARD _CharT* _Get_general_unit_suffix(_CharT* _Rnext, const intmax_t _Num, const intmax_t _Den) { // Returns the head pointer of the string, built in reverse. _STL_INTERNAL_CHECK(_Num > 0 && _Den > 0); *--_Rnext = '\0'; *--_Rnext = 's'; *--_Rnext = ']'; if (_Den != 1) { _Rnext = _UIntegral_to_buff(_Rnext, static_cast(_Den)); *--_Rnext = '/'; } _Rnext = _UIntegral_to_buff(_Rnext, static_cast(_Num)); *--_Rnext = '['; return _Rnext; } template void _Write_unit_suffix(basic_ostream<_CharT, _Traits>& _Os) { constexpr auto _Suffix = _Get_literal_unit_suffix<_CharT, _Period>(); if constexpr (_Suffix == nullptr) { _CharT _Buffer[2 * (numeric_limits::digits10 + 1) + 5] = {}; // 2 numbers + "[/]s\0" const _CharT* const _Begin = _Get_general_unit_suffix<_CharT>(_STD end(_Buffer), _Period::num, _Period::den); _Os << _Begin; } else { _Os << _Suffix; } } template basic_ostream<_CharT, _Traits>& operator<<( basic_ostream<_CharT, _Traits>& _Os, const duration<_Rep, _Period>& _Dur) { basic_ostringstream<_CharT, _Traits> _Sstr; _Sstr.flags(_Os.flags()); _Sstr.imbue(_Os.getloc()); _Sstr.precision(_Os.precision()); _Sstr << _Dur.count(); _Write_unit_suffix<_Period>(_Sstr); return _Os << _Sstr.str(); } struct local_t {}; template using local_time = time_point; using local_seconds = local_time; using local_days = local_time; struct last_spec { explicit last_spec() = default; }; inline constexpr last_spec last{}; class day { public: day() = default; constexpr explicit day(unsigned int _Val) noexcept : _Day{static_cast(_Val)} {} constexpr day& operator++() noexcept { ++_Day; return *this; } constexpr day operator++(int) noexcept { return day{_Day++}; } constexpr day& operator--() noexcept { --_Day; return *this; } constexpr day operator--(int) noexcept { return day{_Day--}; } constexpr day& operator+=(const days& _Days) noexcept { _Day += static_cast(_Days.count()); return *this; } constexpr day& operator-=(const days& _Days) noexcept { _Day -= static_cast(_Days.count()); return *this; } _NODISCARD constexpr explicit operator unsigned int() const noexcept { return _Day; } _NODISCARD constexpr bool ok() const noexcept { return _Day >= 1 && _Day <= 31; } private: unsigned char _Day; }; _NODISCARD constexpr bool operator==(const day& _Left, const day& _Right) noexcept { return static_cast(_Left) == static_cast(_Right); } _NODISCARD constexpr strong_ordering operator<=>(const day& _Left, const day& _Right) noexcept { return static_cast(_Left) <=> static_cast(_Right); } _NODISCARD constexpr day operator+(const day& _Left, const days& _Right) noexcept { return day{static_cast(_Left) + _Right.count()}; } _NODISCARD constexpr day operator+(const days& _Left, const day& _Right) noexcept { return _Right + _Left; } _NODISCARD constexpr day operator-(const day& _Left, const days& _Right) noexcept { return day{static_cast(_Left) - _Right.count()}; } _NODISCARD constexpr days operator-(const day& _Left, const day& _Right) noexcept { return days{ static_cast(static_cast(_Left)) - static_cast(static_cast(_Right))}; } class month { public: month() = default; constexpr explicit month(unsigned int _Val) noexcept : _Month{static_cast(_Val)} {} constexpr month& operator++() noexcept { *this += months{1}; return *this; } constexpr month operator++(int) noexcept { month _Temp{*this}; ++*this; return _Temp; } constexpr month& operator--() noexcept { *this -= months{1}; return *this; } constexpr month operator--(int) noexcept { month _Temp{*this}; --*this; return _Temp; } constexpr month& operator+=(const months& _Months) noexcept; constexpr month& operator-=(const months& _Months) noexcept; _NODISCARD constexpr explicit operator unsigned int() const noexcept { return _Month; } _NODISCARD constexpr bool ok() const noexcept { return _Month >= 1 && _Month <= 12; } private: unsigned char _Month; }; _NODISCARD constexpr bool operator==(const month& _Left, const month& _Right) noexcept { return static_cast(_Left) == static_cast(_Right); } _NODISCARD constexpr strong_ordering operator<=>(const month& _Left, const month& _Right) noexcept { return static_cast(_Left) <=> static_cast(_Right); } _NODISCARD constexpr month operator+(const month& _Left, const months& _Right) noexcept { const auto _Mo = static_cast(static_cast(_Left)) + (_Right.count() - 1); const auto _Div = (_Mo >= 0 ? _Mo : _Mo - 11) / 12; return month{static_cast(_Mo - _Div * 12 + 1)}; } _NODISCARD constexpr month operator+(const months& _Left, const month& _Right) noexcept { return _Right + _Left; } _NODISCARD constexpr month operator-(const month& _Left, const months& _Right) noexcept { return _Left + -_Right; } _NODISCARD constexpr months operator-(const month& _Left, const month& _Right) noexcept { const auto _Mo = static_cast(_Left) - static_cast(_Right); return months{_Mo <= 11 ? _Mo : _Mo + 12}; } constexpr month& month::operator+=(const months& _Months) noexcept { *this = *this + _Months; return *this; } constexpr month& month::operator-=(const months& _Months) noexcept { *this = *this - _Months; return *this; } class year { public: year() = default; constexpr explicit year(int _Val) noexcept : _Year{static_cast(_Val)} {} constexpr year& operator++() noexcept { ++_Year; return *this; } constexpr year operator++(int) noexcept { return year{_Year++}; } constexpr year& operator--() noexcept { --_Year; return *this; } constexpr year operator--(int) noexcept { return year{_Year--}; } constexpr year& operator+=(const years& _Years) noexcept { #ifdef __EDG__ // TRANSITION, VSO-1271098 _Year = static_cast(_Year + _Years.count()); #else // ^^^ workaround / no workaround vvv _Year += static_cast(_Years.count()); #endif // ^^^ no workaround ^^^ return *this; } constexpr year& operator-=(const years& _Years) noexcept { #ifdef __EDG__ // TRANSITION, VSO-1271098 _Year = static_cast(_Year - _Years.count()); #else // ^^^ workaround / no workaround vvv _Year -= static_cast(_Years.count()); #endif // ^^^ no workaround ^^^ return *this; } _NODISCARD constexpr year operator+() const noexcept { return *this; } _NODISCARD constexpr year operator-() const noexcept { return year{-_Year}; } _NODISCARD constexpr bool is_leap() const noexcept { return _Year % 4 == 0 && (_Year % 100 != 0 || _Year % 400 == 0); } _NODISCARD constexpr explicit operator int() const noexcept { return _Year; } _NODISCARD constexpr bool ok() const noexcept { return _Year_min <= _Year && _Year <= _Year_max; } _NODISCARD static constexpr year(min)() noexcept { return year{_Year_min}; } _NODISCARD static constexpr year(max)() noexcept { return year{_Year_max}; } private: short _Year; static constexpr int _Year_min = -32767; static constexpr int _Year_max = 32767; }; _NODISCARD constexpr bool operator==(const year& _Left, const year& _Right) noexcept { return static_cast(_Left) == static_cast(_Right); } _NODISCARD constexpr strong_ordering operator<=>(const year& _Left, const year& _Right) noexcept { return static_cast(_Left) <=> static_cast(_Right); } _NODISCARD constexpr year operator+(const year& _Left, const years& _Right) noexcept { return year{static_cast(_Left) + _Right.count()}; } _NODISCARD constexpr year operator+(const years& _Left, const year& _Right) noexcept { return _Right + _Left; } _NODISCARD constexpr year operator-(const year& _Left, const years& _Right) noexcept { return _Left + -_Right; } _NODISCARD constexpr years operator-(const year& _Left, const year& _Right) noexcept { return years{static_cast(_Left) - static_cast(_Right)}; } class weekday_indexed; class weekday_last; class weekday { public: weekday() = default; constexpr explicit weekday(unsigned int _Val) noexcept : _Weekday{static_cast(_Val == 7 ? 0 : _Val)} {} constexpr weekday(const sys_days& _Sys_day) noexcept : _Weekday{static_cast(_Weekday_from_days(_Sys_day.time_since_epoch().count()))} {} constexpr explicit weekday(const local_days& _Local_day) noexcept : _Weekday{static_cast(_Weekday_from_days(_Local_day.time_since_epoch().count()))} {} constexpr weekday& operator++() noexcept { return *this += days{1}; } constexpr weekday operator++(int) noexcept { weekday _Temp{*this}; ++*this; return _Temp; } constexpr weekday& operator--() noexcept { return *this -= days{1}; } constexpr weekday operator--(int) noexcept { weekday _Temp{*this}; --*this; return _Temp; } constexpr weekday& operator+=(const days& _Days) noexcept; constexpr weekday& operator-=(const days& _Days) noexcept; _NODISCARD constexpr unsigned int c_encoding() const noexcept { return _Weekday; } _NODISCARD constexpr unsigned int iso_encoding() const noexcept { return _Weekday == 0u ? 7u : _Weekday; } _NODISCARD constexpr bool ok() const noexcept { return _Weekday <= 6; } _NODISCARD constexpr weekday_indexed operator[](unsigned int _Index) const noexcept; _NODISCARD constexpr weekday_last operator[](last_spec) const noexcept; private: unsigned char _Weekday; // courtesy of Howard Hinnant // https://howardhinnant.github.io/date_algorithms.html#weekday_from_days _NODISCARD static constexpr unsigned int _Weekday_from_days(int _Tp) noexcept { return static_cast(_Tp >= -4 ? (_Tp + 4) % 7 : (_Tp + 5) % 7 + 6); } }; _NODISCARD constexpr bool operator==(const weekday& _Left, const weekday& _Right) noexcept { return _Left.c_encoding() == _Right.c_encoding(); } _NODISCARD constexpr weekday operator+(const weekday& _Left, const days& _Right) noexcept { const auto _Wd = static_cast(_Left.c_encoding()) + _Right.count(); const auto _Div = (_Wd >= 0 ? _Wd : _Wd - 6) / 7; return weekday{static_cast(_Wd - _Div * 7)}; } _NODISCARD constexpr weekday operator+(const days& _Left, const weekday& _Right) noexcept { return _Right + _Left; } _NODISCARD constexpr weekday operator-(const weekday& _Left, const days& _Right) noexcept { return _Left + -_Right; } _NODISCARD constexpr days operator-(const weekday& _Left, const weekday& _Right) noexcept { const auto _Wd = _Left.c_encoding() - _Right.c_encoding(); const auto _Wk = _Wd <= 6 ? _Wd : _Wd + 7; return days{_Wk}; } constexpr weekday& weekday::operator+=(const days& _Days) noexcept { *this = *this + _Days; return *this; } constexpr weekday& weekday::operator-=(const days& _Days) noexcept { *this = *this - _Days; return *this; } class weekday_indexed { public: weekday_indexed() = default; constexpr weekday_indexed(const weekday& _Wd, unsigned int _Idx) noexcept : _Weekday{_Wd}, _Index{static_cast(_Idx)} {} _NODISCARD constexpr weekday weekday() const noexcept { return _Weekday; } _NODISCARD constexpr unsigned int index() const noexcept { return _Index; } _NODISCARD constexpr bool ok() const noexcept { return _Weekday.ok() && _Index >= 1 && _Index <= 5; } private: _CHRONO weekday _Weekday; unsigned char _Index; }; _NODISCARD constexpr bool operator==(const weekday_indexed& _Left, const weekday_indexed& _Right) noexcept { return _Left.weekday() == _Right.weekday() && _Left.index() == _Right.index(); } class weekday_last { public: constexpr explicit weekday_last(const weekday& _Wd) noexcept : _Weekday{_Wd} {} _NODISCARD constexpr weekday weekday() const noexcept { return _Weekday; } _NODISCARD constexpr bool ok() const noexcept { return _Weekday.ok(); } private: _CHRONO weekday _Weekday; }; _NODISCARD constexpr bool operator==(const weekday_last& _Left, const weekday_last& _Right) noexcept { return _Left.weekday() == _Right.weekday(); } _NODISCARD constexpr weekday_indexed weekday::operator[](unsigned int _Index) const noexcept { return {*this, _Index}; } _NODISCARD constexpr weekday_last weekday::operator[](last_spec) const noexcept { return weekday_last{*this}; } class month_day { public: month_day() = default; constexpr month_day(const month& _Month_, const day& _Day_) noexcept : _Month{_Month_}, _Day{_Day_} {} _NODISCARD constexpr month month() const noexcept { return _Month; } _NODISCARD constexpr day day() const noexcept { return _Day; } _NODISCARD constexpr bool ok() const noexcept { if (!_Month.ok() || !_Day.ok()) { return false; } const auto _Da = static_cast(_Day); const auto _Mo = static_cast(_Month); if (_Mo == 2) { return _Da <= 29; } if (_Mo == 4 || _Mo == 6 || _Mo == 9 || _Mo == 11) { return _Da <= 30; } return true; } private: _CHRONO month _Month; _CHRONO day _Day; }; _NODISCARD constexpr bool operator==(const month_day& _Left, const month_day& _Right) noexcept { return _Left.month() == _Right.month() && _Left.day() == _Right.day(); } _NODISCARD constexpr strong_ordering operator<=>(const month_day& _Left, const month_day& _Right) noexcept { const auto _Comp = _Left.month() <=> _Right.month(); if (_Comp != 0) { return _Comp; } return _Left.day() <=> _Right.day(); } class month_day_last { public: constexpr explicit month_day_last(const month& _Month_) noexcept : _Month{_Month_} {} _NODISCARD constexpr month month() const noexcept { return _Month; } _NODISCARD constexpr bool ok() const noexcept { return _Month.ok(); } private: _CHRONO month _Month; }; _NODISCARD constexpr bool operator==(const month_day_last& _Left, const month_day_last& _Right) noexcept { return _Left.month() == _Right.month(); } _NODISCARD constexpr strong_ordering operator<=>( const month_day_last& _Left, const month_day_last& _Right) noexcept { return _Left.month() <=> _Right.month(); } class month_weekday { public: constexpr month_weekday(const month& _Month_, const weekday_indexed& _Wdi) noexcept : _Month{_Month_}, _Weekday_index{_Wdi} {} _NODISCARD constexpr month month() const noexcept { return _Month; } _NODISCARD constexpr weekday_indexed weekday_indexed() const noexcept { return _Weekday_index; } _NODISCARD constexpr bool ok() const noexcept { return _Month.ok() && _Weekday_index.ok(); } private: _CHRONO month _Month; _CHRONO weekday_indexed _Weekday_index; }; _NODISCARD constexpr bool operator==(const month_weekday& _Left, const month_weekday& _Right) noexcept { return _Left.month() == _Right.month() && _Left.weekday_indexed() == _Right.weekday_indexed(); } class month_weekday_last { public: constexpr month_weekday_last(const month& _Month_, const weekday_last& _Wdl) noexcept : _Month{_Month_}, _Weekday_last{_Wdl} {} _NODISCARD constexpr month month() const noexcept { return _Month; } _NODISCARD constexpr weekday_last weekday_last() const noexcept { return _Weekday_last; } _NODISCARD constexpr bool ok() const noexcept { return _Month.ok() && _Weekday_last.ok(); } private: _CHRONO month _Month; _CHRONO weekday_last _Weekday_last; }; _NODISCARD constexpr bool operator==(const month_weekday_last& _Left, const month_weekday_last& _Right) noexcept { return _Left.month() == _Right.month() && _Left.weekday_last() == _Right.weekday_last(); } class year_month { public: year_month() = default; constexpr year_month(const year& _Year_, const month& _Month_) noexcept : _Year{_Year_}, _Month{_Month_} {} _NODISCARD constexpr year year() const noexcept { return _Year; } _NODISCARD constexpr month month() const noexcept { return _Month; } template constexpr year_month& operator+=(const months& _Months) noexcept; template constexpr year_month& operator-=(const months& _Months) noexcept; constexpr year_month& operator+=(const years& _Years) noexcept; constexpr year_month& operator-=(const years& _Years) noexcept; _NODISCARD constexpr bool ok() const noexcept { return _Year.ok() && _Month.ok(); } private: _CHRONO year _Year; _CHRONO month _Month; }; _NODISCARD constexpr bool operator==(const year_month& _Left, const year_month& _Right) noexcept { return _Left.year() == _Right.year() && _Left.month() == _Right.month(); } _NODISCARD constexpr strong_ordering operator<=>(const year_month& _Left, const year_month& _Right) noexcept { const auto _Comp = _Left.year() <=> _Right.year(); if (_Comp != 0) { return _Comp; } return _Left.month() <=> _Right.month(); } template _NODISCARD constexpr year_month operator+(const year_month& _Left, const months& _Right) noexcept { const auto _Mo = static_cast(static_cast(_Left.month())) + (_Right.count() - 1); const auto _Div = (_Mo >= 0 ? _Mo : _Mo - 11) / 12; return year_month{_Left.year() + years{_Div}, month{static_cast(_Mo - _Div * 12 + 1)}}; } template _NODISCARD constexpr year_month operator+(const months& _Left, const year_month& _Right) noexcept { return _Right + _Left; } template _NODISCARD constexpr year_month operator-(const year_month& _Left, const months& _Right) noexcept { return _Left + -_Right; } _NODISCARD constexpr months operator-(const year_month& _Left, const year_month& _Right) noexcept { return _Left.year() - _Right.year() + months{static_cast(static_cast(_Left.month())) - static_cast(static_cast(_Right.month()))}; } _NODISCARD constexpr year_month operator+(const year_month& _Left, const years& _Right) noexcept { return {year{_Left.year() + _Right}, _Left.month()}; } _NODISCARD constexpr year_month operator+(const years& _Left, const year_month& _Right) noexcept { return _Right + _Left; } _NODISCARD constexpr year_month operator-(const year_month& _Left, const years& _Right) noexcept { return _Left + -_Right; } template constexpr year_month& year_month::operator+=(const months& _Months) noexcept { *this = *this + _Months; return *this; } template constexpr year_month& year_month::operator-=(const months& _Months) noexcept { *this = *this - _Months; return *this; } constexpr year_month& year_month::operator+=(const years& _Years) noexcept { *this = *this + _Years; return *this; } constexpr year_month& year_month::operator-=(const years& _Years) noexcept { *this = *this - _Years; return *this; } // To prevent UB by going out of bounds, four extra days with an invalid day are added. inline constexpr day _Last_day_table[] = {day{31}, day{28}, day{31}, day{30}, day{31}, day{30}, day{31}, day{31}, day{30}, day{31}, day{30}, day{31}, day{255}, day{255}, day{255}, day{255}}; _NODISCARD constexpr day _Last_day(const year& _Year, const month& _Month) { if (_Month == month{2} && _Year.is_leap()) { return day{29}; } return _Last_day_table[(static_cast(_Month) - 1) & 0xF]; } class year_month_day_last; class year_month_day { public: year_month_day() = default; constexpr year_month_day(const year& _Year_, const month& _Month_, const day& _Day_) noexcept : _Year{_Year_}, _Month{_Month_}, _Day{_Day_} {} constexpr year_month_day(const year_month_day_last& _Ymdl) noexcept; constexpr year_month_day(const sys_days& _Sys_days) noexcept : year_month_day{_Civil_from_days(_Sys_days.time_since_epoch().count())} {} constexpr explicit year_month_day(const local_days& _Local_days) noexcept : year_month_day{_Civil_from_days(_Local_days.time_since_epoch().count())} {} template constexpr year_month_day& operator+=(const months& _Months) noexcept; template constexpr year_month_day& operator-=(const months& _Months) noexcept; constexpr year_month_day& operator+=(const years& _Years) noexcept; constexpr year_month_day& operator-=(const years& _Years) noexcept; _NODISCARD constexpr year year() const noexcept { return _Year; } _NODISCARD constexpr month month() const noexcept { return _Month; } _NODISCARD constexpr day day() const noexcept { return _Day; } _NODISCARD constexpr operator sys_days() const noexcept { return sys_days{_Days_from_civil()}; } _NODISCARD constexpr explicit operator local_days() const noexcept { return local_days{static_cast(*this).time_since_epoch()}; } _NODISCARD constexpr bool ok() const noexcept { if (!_Year.ok() || !_Month.ok()) { return false; } return _Day >= _CHRONO day{1} && _Day <= _Last_day(_Year, _Month); } _NODISCARD constexpr int _Calculate_weekday() const noexcept { const int _Day_int = static_cast(static_cast(_Day)); const int _Month_int = static_cast(static_cast(_Month)); const int _Era_year = static_cast(_Year) - (_Month_int <= 2); const int _Era = (_Era_year >= 0 ? _Era_year : _Era_year - 399) / 400; const int _Yoe = _Era_year - _Era * 400; const int _Yday_era = ((979 * (_Month_int + (_Month_int > 2 ? -3 : 9)) + 19) >> 5) + _Day_int - 1; const int _Doe = ((1461 * _Yoe) >> 2) - _Yoe / 100 + _Yday_era; return (_Doe + 3) % 7; // the era began on a Wednesday } private: _CHRONO year _Year; _CHRONO month _Month; _CHRONO day _Day; // _Civil_from_days and _Days_from_civil perform conversions between the dates in the (proleptic) Gregorian // calendar and the continuous count of days since 1970-01-01. // To simplify the handling of leap days (February 29th), the algorithm below uses a modified calendar // internally, in which each year begins on March 1st, while January and February belong to the previous year. // We denote the modified year and month number as _Yp and _Mp. We also define modified centuries that begin on // each modified year whose _Yp is a multiple of 100. // _Mp | Month | Day of Year // --- | --------- | ----------- // 0 | March | [ 0, 30] // 1 | April | [ 31, 60] // 2 | May | [ 61, 91] // 3 | June | [ 92, 121] // 4 | July | [122, 152] // 5 | August | [153, 183] // 6 | September | [184, 213] // 7 | October | [214, 244] // 8 | November | [245, 274] // 9 | December | [275, 305] // 10 | January | [306, 336] // 11 | February | [337, 365] on leap years, [337, 364] on regular years // _Yp | First Day | Last Day (inclusive) | Leap Year? // --- | ----------- | -------------------- | ---------- // -4 | -0004-03-01 | -0003-02-28 | No // -3 | -0003-03-01 | -0002-02-28 | No // -2 | -0002-03-01 | -0001-02-28 | No // -1 | -0001-03-01 | 0000-02-29 | Yes // 0 | 0000-03-01 | 0001-02-28 | No // 1 | 0001-03-01 | 0002-02-28 | No // 2 | 0002-03-01 | 0003-02-28 | No // 3 | 0003-03-01 | 0004-02-29 | Yes // _Century | First Day | Last Day (inclusive) | Long Century? // -------- | ----------- | -------------------- | ------------- // -4 | -0400-03-01 | -0300-02-28 | No // -3 | -0300-03-01 | -0200-02-28 | No // -2 | -0200-03-01 | -0100-02-28 | No // -1 | -0100-03-01 | 0000-02-29 | Yes // 0 | 0000-03-01 | 0100-02-28 | No // 1 | 0100-03-01 | 0200-02-28 | No // 2 | 0200-03-01 | 0300-02-28 | No // 3 | 0300-03-01 | 0400-02-29 | Yes // The structure of the modified calendar: // 1 ) It has a period of 4 centuries. // 2 ) Each calendar period (146097 days) contains 3 regular centuries followed by a long century (36525 days). // 3 ) Each regular century (36524 days) contains 24 regular 4-year spans followed by a short 4-year span. // 3') Each long century (36525 days) contains 25 regular 4-year spans. // 4 ) Each regular 4-year span (1461 days) contains 3 regular years followed by a leap year. // 4') Each short 4-year span (1460 days) contains 4 regular years. // Formula 1: Compute _Day_of_year of the first day of month _Mp // // _Day_of_year = (979 * _Mp + 19) >> 5 // // A more well-known formula is 30 * _Mp + floor((3 * _Mp + 2) / 5) or floor((153 * _Mp + 2) / 5), which is used // in Howard Hinnant's paper. // // The formula above returns the same result for all _Mp in [0, 11]. // Note that 979 / 2^5 = 30.59375 ~= 30.6 = 153 / 5. // Formula 1': Compute _Mp from _Day_of_year // // _Mp = (535 * _Day_of_year + 333) >> 14 // // Howard Hinnant's paper uses floor((5 * _Day_of_year + 2) / 153), the inverse of floor((153 * _Mp + 2) / 5) or // ceil((153 * _Mp - 2) / 5). // // The formula above returns the same result for all _Day_of_year in [0, 365]. // Note that 2^14 / 535 = 30.624... ~= 30.6 = 153 / 5. // Formula 2: Compute _Zx of the first day of year _Yp, where _Zx is the continuous count of days since // 0000-03-01. // // _Zx = ((1461 * _Yp) >> 2) - _Century + (_Century >> 2) // // Start with multiplying by the number of days in regular years (365), add one day for the leap year in each // 4-year span, subtract one day for the short 4-year span in each century, and finally add one day for the long // century in each calendar period. This gives us 365 * _Yp + floor(_Yp / 4) - _Century + floor(_Century / 4). // Formula 2-1: Compute _Day_of_century of the first day of year _Year_of_century // // _Day_of_century = (1461 * _Year_of_century) >> 2 // // Start with multiplying by the number of days in regular years (365), add one day for the leap year in each // 4-year span. This gives us 365 * _Year_of_century + floor(_Year_of_century / 4) // == floor(1461 * _Year_of_century / 4). // Formula 2-1': Compute _Year_of_century from _Day_of_century // // _Year_of_century = (91867 * (_Day_of_century + 1)) >> 25 // // The inverse of floor(1461 * _Year_of_century / 4) or ceil((1461 * _Year_of_century - 3) / 4) is // floor((4 * _Day_of_century + 3) / 1461). // // The formula above returns the same result for all _Day_of_century in [0, 36524]. // Note that 2^25 / 91867 = 365.2501... ~= 365.25 = 1461 / 4. // Formula 2-2: Compute _Zx of the first day of century _Century, where _Zx is the continuous count of days // since 0000-03-01. // // _Zx = (146097 * _Century) >> 2 // // Start with multiplying by the number of days in regular centuries (36524), add one day for the long century // in each calendar period. This gives us 36524 * _Century + floor(_Century / 4) = floor(146097 * _Century / 4). // Formula 2-2': Compute _Century from _Zx, where _Zx is the continuous count of days since 0000-03-01. // // _Century = floor((4 * _Zx + 3) / 146097) // // This is the inverse of floor(146097 * _Year_of_century / 4) or ceil((146097 * _Year_of_century - 3) / 4) // courtesy of Howard Hinnant // https://howardhinnant.github.io/date_algorithms.html#civil_from_days _NODISCARD static constexpr year_month_day _Civil_from_days(int _Tp) noexcept { static_assert(numeric_limits::digits >= 32); static_assert(numeric_limits::digits >= 26); const int _Zx = _Tp + 719468; // Shift epoch to 0000-03-01 // Formula 2-2' const int _Century = (_Zx >= 0 ? 4 * _Zx + 3 : 4 * _Zx - 146093) / 146097; // Formula 2-2 const unsigned int _Day_of_century = static_cast(_Zx - ((146097 * _Century) >> 2)); // [0, 36524] // Formula 2-1' const unsigned int _Year_of_century = (91867 * (_Day_of_century + 1)) >> 25; // [0, 99] const int _Yp = static_cast(_Year_of_century) + _Century * 100; // Where March is the first month // Formula 2-1 const unsigned int _Day_of_year = _Day_of_century - ((1461 * _Year_of_century) >> 2); // [0, 365] // Formula 1' const unsigned int _Mp = (535 * _Day_of_year + 333) >> 14; // [0, 11] // Formula 1 const unsigned int _Day = _Day_of_year - ((979 * _Mp + 19) >> 5) + 1; // [1, 31] const unsigned int _Month = _Mp + (_Mp < 10 ? 3 : static_cast(-9)); // [1, 12] return year_month_day{_CHRONO year{_Yp + (_Month <= 2)}, _CHRONO month{_Month}, _CHRONO day{_Day}}; } // courtesy of Howard Hinnant // https://howardhinnant.github.io/date_algorithms.html#days_from_civil _NODISCARD constexpr days _Days_from_civil() const noexcept { static_assert(numeric_limits::digits >= 18); static_assert(numeric_limits::digits >= 26); const unsigned int _Mo = static_cast(_Month); // [1, 12] const int _Yp = static_cast(_Year) - (_Mo <= 2); const int _Century = (_Yp >= 0 ? _Yp : _Yp - 99) / 100; const unsigned int _Mp = _Mo + (_Mo > 2 ? static_cast(-3) : 9); // [0, 11] // Formula 1 const int _Day_of_year = static_cast(((979 * _Mp + 19) >> 5) + static_cast(_Day)) - 1; // Formula 2 return days{((1461 * _Yp) >> 2) - _Century + (_Century >> 2) + _Day_of_year - 719468}; } }; _NODISCARD constexpr bool operator==(const year_month_day& _Left, const year_month_day& _Right) noexcept { return _Left.year() == _Right.year() && _Left.month() == _Right.month() && _Left.day() == _Right.day(); } _NODISCARD constexpr strong_ordering operator<=>( const year_month_day& _Left, const year_month_day& _Right) noexcept { auto _Comp = _Left.year() <=> _Right.year(); if (_Comp != 0) { return _Comp; } _Comp = _Left.month() <=> _Right.month(); if (_Comp != 0) { return _Comp; } return _Left.day() <=> _Right.day(); } template _NODISCARD constexpr year_month_day operator+(const year_month_day& _Left, const months& _Right) noexcept { const auto _Ym = year_month{_Left.year(), _Left.month()} + _Right; return {_Ym.year(), _Ym.month(), _Left.day()}; } template _NODISCARD constexpr year_month_day operator+(const months& _Left, const year_month_day& _Right) noexcept { return _Right + _Left; } template _NODISCARD constexpr year_month_day operator-(const year_month_day& _Left, const months& _Right) noexcept { return _Left + -_Right; } _NODISCARD constexpr year_month_day operator+(const year_month_day& _Left, const years& _Right) noexcept { return {_Left.year() + _Right, _Left.month(), _Left.day()}; } _NODISCARD constexpr year_month_day operator+(const years& _Left, const year_month_day& _Right) noexcept { return _Right + _Left; } _NODISCARD constexpr year_month_day operator-(const year_month_day& _Left, const years& _Right) noexcept { return _Left + -_Right; } template constexpr year_month_day& year_month_day::operator+=(const months& _Months) noexcept { *this = *this + _Months; return *this; } template constexpr year_month_day& year_month_day::operator-=(const months& _Months) noexcept { *this = *this - _Months; return *this; } constexpr year_month_day& year_month_day::operator+=(const years& _Years) noexcept { *this = *this + _Years; return *this; } constexpr year_month_day& year_month_day::operator-=(const years& _Years) noexcept { *this = *this - _Years; return *this; } class year_month_day_last { public: constexpr year_month_day_last(const year& _Year_, const month_day_last& _Mdl) noexcept : _Year{_Year_}, _Month_day_last{_Mdl} {} template constexpr year_month_day_last& operator+=(const months& _Months) noexcept; template constexpr year_month_day_last& operator-=(const months& _Months) noexcept; constexpr year_month_day_last& operator+=(const years& _Years) noexcept; constexpr year_month_day_last& operator-=(const years& _Years) noexcept; _NODISCARD constexpr year year() const noexcept { return _Year; } _NODISCARD constexpr month month() const noexcept { return _Month_day_last.month(); } _NODISCARD constexpr month_day_last month_day_last() const noexcept { return _Month_day_last; } _NODISCARD constexpr day day() const noexcept { return _Last_day(year(), month()); } _NODISCARD constexpr operator sys_days() const noexcept { return sys_days{year_month_day{year(), month(), day()}}; } _NODISCARD constexpr explicit operator local_days() const noexcept { return local_days{static_cast(*this).time_since_epoch()}; } _NODISCARD constexpr bool ok() const noexcept { return _Year.ok() && _Month_day_last.ok(); } private: _CHRONO year _Year; _CHRONO month_day_last _Month_day_last; }; _NODISCARD constexpr bool operator==(const year_month_day_last& _Left, const year_month_day_last& _Right) noexcept { return _Left.year() == _Right.year() && _Left.month_day_last() == _Right.month_day_last(); } _NODISCARD constexpr strong_ordering operator<=>( const year_month_day_last& _Left, const year_month_day_last& _Right) noexcept { const auto _Comp = _Left.year() <=> _Right.year(); if (_Comp != 0) { return _Comp; } return _Left.month_day_last() <=> _Right.month_day_last(); } template _NODISCARD constexpr year_month_day_last operator+( const year_month_day_last& _Left, const months& _Right) noexcept { const auto _Ym = year_month{_Left.year(), _Left.month()} + _Right; return {_Ym.year(), month_day_last{_Ym.month()}}; } template _NODISCARD constexpr year_month_day_last operator+( const months& _Left, const year_month_day_last& _Right) noexcept { return _Right + _Left; } template _NODISCARD constexpr year_month_day_last operator-( const year_month_day_last& _Left, const months& _Right) noexcept { return _Left + -_Right; } _NODISCARD constexpr year_month_day_last operator+(const year_month_day_last& _Left, const years& _Right) noexcept { return {_Left.year() + _Right, _Left.month_day_last()}; } _NODISCARD constexpr year_month_day_last operator+(const years& _Left, const year_month_day_last& _Right) noexcept { return _Right + _Left; } _NODISCARD constexpr year_month_day_last operator-(const year_month_day_last& _Left, const years& _Right) noexcept { return _Left + -_Right; } template constexpr year_month_day_last& year_month_day_last::operator+=(const months& _Months) noexcept { *this = *this + _Months; return *this; } template constexpr year_month_day_last& year_month_day_last::operator-=(const months& _Months) noexcept { *this = *this - _Months; return *this; } constexpr year_month_day_last& year_month_day_last::operator+=(const years& _Years) noexcept { *this = *this + _Years; return *this; } constexpr year_month_day_last& year_month_day_last::operator-=(const years& _Years) noexcept { *this = *this - _Years; return *this; } constexpr year_month_day::year_month_day(const year_month_day_last& _Ymdl) noexcept : _Year{_Ymdl.year()}, _Month{_Ymdl.month()}, _Day{_Ymdl.day()} {} class year_month_weekday { public: year_month_weekday() = default; constexpr year_month_weekday(const year& _Year_, const month& _Month_, const weekday_indexed& _Wdi) noexcept : _Year{_Year_}, _Month{_Month_}, _Weekday_index{_Wdi} {} constexpr year_month_weekday(const sys_days& _Sys_days) noexcept : year_month_weekday{_Ymwd_from_days(_Sys_days.time_since_epoch())} {} constexpr explicit year_month_weekday(const local_days& _Local_days) noexcept : year_month_weekday{_Ymwd_from_days(_Local_days.time_since_epoch())} {} template constexpr year_month_weekday& operator+=(const months& _Months) noexcept; template constexpr year_month_weekday& operator-=(const months& _Months) noexcept; constexpr year_month_weekday& operator+=(const years& _Years) noexcept; constexpr year_month_weekday& operator-=(const years& _Years) noexcept; _NODISCARD constexpr year year() const noexcept { return _Year; } _NODISCARD constexpr month month() const noexcept { return _Month; } _NODISCARD constexpr weekday weekday() const noexcept { return _Weekday_index.weekday(); } _NODISCARD constexpr unsigned int index() const noexcept { return _Weekday_index.index(); } _NODISCARD constexpr weekday_indexed weekday_indexed() const noexcept { return _Weekday_index; } _NODISCARD constexpr operator sys_days() const noexcept { const sys_days _First = year_month_day{_Year, _Month, day{1}}; const days _Diff = weekday() - _CHRONO weekday{_First}; const days _Days = _Diff + days{(static_cast(index()) - 1) * 7}; return _First + _Days; } _NODISCARD constexpr explicit operator local_days() const noexcept { return local_days{static_cast(*this).time_since_epoch()}; } _NODISCARD constexpr bool ok() const noexcept { if (!_Year.ok() || !_Month.ok() || !_Weekday_index.ok()) { return false; } if (_Weekday_index.index() <= 4) { return true; } // As index() == 5 is not always valid // Determine the date of the first weekday and check if + days{28} is <= last day of the month const sys_days _First_of_month = year_month_day{_Year, _Month, day{1}}; const days _First_weekday = weekday() - _CHRONO weekday{_First_of_month} + days{1}; const days _Last = _First_weekday + days{28}; return static_cast(_Last.count()) <= static_cast(_Last_day(_Year, _Month)); } private: _CHRONO year _Year; _CHRONO month _Month; _CHRONO weekday_indexed _Weekday_index; _NODISCARD static constexpr year_month_weekday _Ymwd_from_days(days _Dp) noexcept { const _CHRONO year_month_day _Ymd = sys_days{_Dp}; const _CHRONO weekday _Wd = sys_days{_Dp}; const auto _Idx = ((static_cast(_Ymd.day()) - 1) / 7) + 1; return {_Ymd.year(), _Ymd.month(), _Wd[_Idx]}; } }; _NODISCARD constexpr bool operator==(const year_month_weekday& _Left, const year_month_weekday& _Right) noexcept { return _Left.year() == _Right.year() && _Left.month() == _Right.month() && _Left.weekday_indexed() == _Right.weekday_indexed(); } template _NODISCARD constexpr year_month_weekday operator+(const year_month_weekday& _Left, const months& _Right) noexcept { const auto _Ym = year_month{_Left.year(), _Left.month()} + _Right; return {_Ym.year(), _Ym.month(), _Left.weekday_indexed()}; } template _NODISCARD constexpr year_month_weekday operator+(const months& _Left, const year_month_weekday& _Right) noexcept { return _Right + _Left; } template _NODISCARD constexpr year_month_weekday operator-(const year_month_weekday& _Left, const months& _Right) noexcept { return _Left + -_Right; } _NODISCARD constexpr year_month_weekday operator+(const year_month_weekday& _Left, const years& _Right) noexcept { return year_month_weekday{_Left.year() + _Right, _Left.month(), _Left.weekday_indexed()}; } _NODISCARD constexpr year_month_weekday operator+(const years& _Left, const year_month_weekday& _Right) noexcept { return _Right + _Left; } _NODISCARD constexpr year_month_weekday operator-(const year_month_weekday& _Left, const years& _Right) noexcept { return _Left + -_Right; } template constexpr year_month_weekday& year_month_weekday::operator+=(const months& _Months) noexcept { *this = *this + _Months; return *this; } template constexpr year_month_weekday& year_month_weekday::operator-=(const months& _Months) noexcept { *this = *this - _Months; return *this; } constexpr year_month_weekday& year_month_weekday::operator+=(const years& _Years) noexcept { *this = *this + _Years; return *this; } constexpr year_month_weekday& year_month_weekday::operator-=(const years& _Years) noexcept { *this = *this - _Years; return *this; } class year_month_weekday_last { public: constexpr year_month_weekday_last(const year& _Year_, const month& _Month_, const weekday_last& _Wdl) noexcept : _Year{_Year_}, _Month{_Month_}, _Weekday_last{_Wdl} {} template constexpr year_month_weekday_last& operator+=(const months& _Months) noexcept; template constexpr year_month_weekday_last& operator-=(const months& _Months) noexcept; constexpr year_month_weekday_last& operator+=(const years& _Years) noexcept; constexpr year_month_weekday_last& operator-=(const years& _Years) noexcept; _NODISCARD constexpr year year() const noexcept { return _Year; } _NODISCARD constexpr month month() const noexcept { return _Month; } _NODISCARD constexpr weekday weekday() const noexcept { return _Weekday_last.weekday(); } _NODISCARD constexpr weekday_last weekday_last() const noexcept { return _Weekday_last; } _NODISCARD constexpr operator sys_days() const noexcept { const sys_days _Last = year_month_day_last{_Year, month_day_last{_Month}}; const auto _Diff = _CHRONO weekday{_Last} - weekday(); return _Last - _Diff; } _NODISCARD constexpr explicit operator local_days() const noexcept { return local_days{static_cast(*this).time_since_epoch()}; } _NODISCARD constexpr bool ok() const noexcept { return _Year.ok() && _Month.ok() && _Weekday_last.ok(); } private: _CHRONO year _Year; _CHRONO month _Month; _CHRONO weekday_last _Weekday_last; }; _NODISCARD constexpr bool operator==( const year_month_weekday_last& _Left, const year_month_weekday_last& _Right) noexcept { return _Left.year() == _Right.year() && _Left.month() == _Right.month() && _Left.weekday_last() == _Right.weekday_last(); } template _NODISCARD constexpr year_month_weekday_last operator+( const year_month_weekday_last& _Left, const months& _Right) noexcept { const auto _Ym = year_month{_Left.year(), _Left.month()} + _Right; return {_Ym.year(), _Ym.month(), _Left.weekday_last()}; } template _NODISCARD constexpr year_month_weekday_last operator+( const months& _Left, const year_month_weekday_last& _Right) noexcept { return _Right + _Left; } template _NODISCARD constexpr year_month_weekday_last operator-( const year_month_weekday_last& _Left, const months& _Right) noexcept { return _Left + -_Right; } _NODISCARD constexpr year_month_weekday_last operator+( const year_month_weekday_last& _Left, const years& _Right) noexcept { return {_Left.year() + _Right, _Left.month(), _Left.weekday_last()}; } _NODISCARD constexpr year_month_weekday_last operator+( const years& _Left, const year_month_weekday_last& _Right) noexcept { return _Right + _Left; } _NODISCARD constexpr year_month_weekday_last operator-( const year_month_weekday_last& _Left, const years& _Right) noexcept { return _Left + -_Right; } template constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const months& _Months) noexcept { *this = *this + _Months; return *this; } template constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const months& _Months) noexcept { *this = *this - _Months; return *this; } constexpr year_month_weekday_last& year_month_weekday_last::operator+=(const years& _Years) noexcept { *this = *this + _Years; return *this; } constexpr year_month_weekday_last& year_month_weekday_last::operator-=(const years& _Years) noexcept { *this = *this - _Years; return *this; } // Civil calendar conventional syntax operators _NODISCARD constexpr year_month operator/(const year& _Year, const month& _Month) noexcept { return {_Year, _Month}; } _NODISCARD constexpr year_month operator/(const year& _Year, int _Month) noexcept { return _Year / month{static_cast(_Month)}; } _NODISCARD constexpr month_day operator/(const month& _Month, const day& _Day) noexcept { return {_Month, _Day}; } _NODISCARD constexpr month_day operator/(const month& _Month, int _Day) noexcept { return _Month / day{static_cast(_Day)}; } _NODISCARD constexpr month_day operator/(int _Month, const day& _Day) noexcept { return month{static_cast(_Month)} / _Day; } _NODISCARD constexpr month_day operator/(const day& _Day, const month& _Month) noexcept { return _Month / _Day; } _NODISCARD constexpr month_day operator/(const day& _Day, int _Month) noexcept { return month{static_cast(_Month)} / _Day; } _NODISCARD constexpr month_day_last operator/(const month& _Month, last_spec) noexcept { return month_day_last{_Month}; } _NODISCARD constexpr month_day_last operator/(int _Month, last_spec) noexcept { return month{static_cast(_Month)} / last; } _NODISCARD constexpr month_day_last operator/(last_spec, const month& _Month) noexcept { return _Month / last; } _NODISCARD constexpr month_day_last operator/(last_spec, int _Month) noexcept { return month{static_cast(_Month)} / last; } _NODISCARD constexpr month_weekday operator/(const month& _Month, const weekday_indexed& _Wdi) noexcept { return {_Month, _Wdi}; } _NODISCARD constexpr month_weekday operator/(int _Month, const weekday_indexed& _Wdi) noexcept { return month{static_cast(_Month)} / _Wdi; } _NODISCARD constexpr month_weekday operator/(const weekday_indexed& _Wdi, const month& _Month) noexcept { return _Month / _Wdi; } _NODISCARD constexpr month_weekday operator/(const weekday_indexed& _Wdi, int _Month) noexcept { return month{static_cast(_Month)} / _Wdi; } _NODISCARD constexpr month_weekday_last operator/(const month& _Month, const weekday_last& _Wdl) noexcept { return {_Month, _Wdl}; } _NODISCARD constexpr month_weekday_last operator/(int _Month, const weekday_last& _Wdl) noexcept { return month{static_cast(_Month)} / _Wdl; } _NODISCARD constexpr month_weekday_last operator/(const weekday_last& _Wdl, const month& _Month) noexcept { return _Month / _Wdl; } _NODISCARD constexpr month_weekday_last operator/(const weekday_last& _Wdl, int _Month) noexcept { return month{static_cast(_Month)} / _Wdl; } _NODISCARD constexpr year_month_day operator/(const year_month& _Ym, const day& _Day) noexcept { return {_Ym.year(), _Ym.month(), _Day}; } _NODISCARD constexpr year_month_day operator/(const year_month& _Ym, int _Day) noexcept { return _Ym / day{static_cast(_Day)}; } _NODISCARD constexpr year_month_day operator/(const year& _Year, const month_day& _Md) noexcept { return _Year / _Md.month() / _Md.day(); } _NODISCARD constexpr year_month_day operator/(int _Year, const month_day& _Md) noexcept { return year{_Year} / _Md.month() / _Md.day(); } _NODISCARD constexpr year_month_day operator/(const month_day& _Md, const year& _Year) noexcept { return _Year / _Md.month() / _Md.day(); } _NODISCARD constexpr year_month_day operator/(const month_day& _Md, int _Year) noexcept { return year{_Year} / _Md.month() / _Md.day(); } _NODISCARD constexpr year_month_day_last operator/(const year_month& _Ym, last_spec) noexcept { return {_Ym.year(), month_day_last{_Ym.month()}}; } _NODISCARD constexpr year_month_day_last operator/(const year& _Year, const month_day_last& _Mdl) noexcept { return {_Year, _Mdl}; } _NODISCARD constexpr year_month_day_last operator/(int _Year, const month_day_last& _Mdl) noexcept { return year{_Year} / _Mdl; } _NODISCARD constexpr year_month_day_last operator/(const month_day_last& _Mdl, const year& _Year) noexcept { return _Year / _Mdl; } _NODISCARD constexpr year_month_day_last operator/(const month_day_last& _Mdl, int _Year) noexcept { return year{_Year} / _Mdl; } _NODISCARD constexpr year_month_weekday operator/(const year_month& _Ym, const weekday_indexed& _Wdi) noexcept { return year_month_weekday{_Ym.year(), _Ym.month(), _Wdi}; } _NODISCARD constexpr year_month_weekday operator/(const year& _Year, const month_weekday& _Mwd) noexcept { return year_month_weekday{_Year, _Mwd.month(), _Mwd.weekday_indexed()}; } _NODISCARD constexpr year_month_weekday operator/(int _Year, const month_weekday& _Mwd) noexcept { return year{_Year} / _Mwd; } _NODISCARD constexpr year_month_weekday operator/(const month_weekday& _Mwd, const year& _Year) noexcept { return _Year / _Mwd; } _NODISCARD constexpr year_month_weekday operator/(const month_weekday& _Mwd, int _Year) noexcept { return year{_Year} / _Mwd; } _NODISCARD constexpr year_month_weekday_last operator/(const year_month& _Ym, const weekday_last& _Wdl) noexcept { return {_Ym.year(), _Ym.month(), _Wdl}; } _NODISCARD constexpr year_month_weekday_last operator/( const year& _Year, const month_weekday_last& _Mwdl) noexcept { return {_Year, _Mwdl.month(), _Mwdl.weekday_last()}; } _NODISCARD constexpr year_month_weekday_last operator/(int _Year, const month_weekday_last& _Mwdl) noexcept { return year{_Year} / _Mwdl; } _NODISCARD constexpr year_month_weekday_last operator/( const month_weekday_last& _Mwdl, const year& _Year) noexcept { return _Year / _Mwdl; } _NODISCARD constexpr year_month_weekday_last operator/(const month_weekday_last& _Mwdl, int _Year) noexcept { return year{_Year} / _Mwdl; } // Calendrical constants inline constexpr weekday Sunday{0}; inline constexpr weekday Monday{1}; inline constexpr weekday Tuesday{2}; inline constexpr weekday Wednesday{3}; inline constexpr weekday Thursday{4}; inline constexpr weekday Friday{5}; inline constexpr weekday Saturday{6}; inline constexpr month January{1}; inline constexpr month February{2}; inline constexpr month March{3}; inline constexpr month April{4}; inline constexpr month May{5}; inline constexpr month June{6}; inline constexpr month July{7}; inline constexpr month August{8}; inline constexpr month September{9}; inline constexpr month October{10}; inline constexpr month November{11}; inline constexpr month December{12}; _NODISCARD constexpr intmax_t _Pow10(const unsigned int _Exp) { intmax_t _Result = 1; for (unsigned int _Ix = 0; _Ix < _Exp; ++_Ix) { _Result *= 10; } return _Result; } template class hh_mm_ss { public: static_assert(_Is_duration_v<_Duration>, "N4885 [time.hms.overview]/2 mandates Duration to be a specialization of chrono::duration."); static constexpr unsigned int fractional_width = [] { auto _Num = _Duration::period::num; constexpr auto _Den = _Duration::period::den; // Returns the number of fractional digits of _Num / _Den in the range [0, 18]. // If it can't be represented, 6 is returned. // Example: _Fractional_width(1, 8) would return 3 for 0.125. _STL_ASSERT(_Num > 0 && _Den > 0, "Numerator and denominator can't be less than 1."); unsigned int _Result = 0; for (; _Num % _Den != 0 && _Result < 19; _Num = _Num % _Den * 10, ++_Result) { } return _Result == 19 ? 6 : _Result; }(); using precision = duration, ratio<1, _Pow10(fractional_width)>>; constexpr hh_mm_ss() noexcept : hh_mm_ss{_Duration::zero()} {} // clang-format off constexpr explicit hh_mm_ss(_Duration _Dur) : _Is_neg{_Dur < _Duration::zero()}, _Hours{_CHRONO duration_cast<_CHRONO hours>(_CHRONO abs(_Dur))}, _Mins{_CHRONO duration_cast<_CHRONO minutes>(_CHRONO abs(_Dur) - hours())}, _Secs{_CHRONO duration_cast<_CHRONO seconds>(_CHRONO abs(_Dur) - hours() - minutes())} { // clang-format on if constexpr (treat_as_floating_point_v) { _Sub_secs = _CHRONO abs(_Dur) - hours() - minutes() - seconds(); } else { _Sub_secs = _CHRONO duration_cast(_CHRONO abs(_Dur) - hours() - minutes() - seconds()); } } _NODISCARD constexpr bool is_negative() const noexcept { return _Is_neg; } _NODISCARD constexpr hours hours() const noexcept { return _Hours; } _NODISCARD constexpr minutes minutes() const noexcept { return _Mins; } _NODISCARD constexpr seconds seconds() const noexcept { return _Secs; } _NODISCARD constexpr precision subseconds() const noexcept { return _Sub_secs; } _NODISCARD constexpr explicit operator precision() const noexcept { return to_duration(); } _NODISCARD constexpr precision to_duration() const noexcept { const auto _Dur = _Hours + _Mins + _Secs + _Sub_secs; return _Is_neg ? -_Dur : _Dur; } private: bool _Is_neg; _CHRONO hours _Hours; _CHRONO minutes _Mins; _CHRONO seconds _Secs; precision _Sub_secs; }; _NODISCARD constexpr bool is_am(const hours& _Hours) noexcept { return _Hours >= hours{0} && _Hours <= hours{11}; } _NODISCARD constexpr bool is_pm(const hours& _Hours) noexcept { return _Hours >= hours{12} && _Hours <= hours{23}; } _NODISCARD constexpr hours make12(const hours& _Hours) noexcept { const auto _H_count{_Hours.count()}; auto _Ret{_H_count == 0 ? 12 : _H_count}; if (_Ret > 12) { _Ret -= 12; } return hours{_Ret}; } _NODISCARD constexpr hours make24(const hours& _Hours, bool _Is_pm) noexcept { const auto _H_count{_Hours.count()}; auto _Ret{_H_count == 12 ? 0 : _H_count}; if (_Is_pm) { _Ret += 12; } return hours{_Ret}; } // [time.zone.info] struct sys_info { sys_seconds begin; sys_seconds end; seconds offset; minutes save; string abbrev; }; struct local_info { static constexpr int unique = 0; static constexpr int nonexistent = 1; static constexpr int ambiguous = 2; int result; sys_info first; sys_info second; }; class nonexistent_local_time : public runtime_error { public: template nonexistent_local_time(const local_time<_Duration>& _Tp, const local_info& _Info) : runtime_error(_Make_string(_Tp, _Info)) {} private: #ifdef __cpp_lib_format template _NODISCARD static string _Make_string(const local_time<_Duration>& _Tp, const local_info& _Info); #else // ^^^ no workaround / workaround vvv template _NODISCARD static string _Make_string(const local_time<_Duration>&, const local_info&) { return "nonexistent_local_time"; } #endif // ^^^ workaround ^^^ }; class ambiguous_local_time : public runtime_error { public: template ambiguous_local_time(const local_time<_Duration>& _Tp, const local_info& _Info) : runtime_error(_Make_string(_Tp, _Info)) {} private: #ifdef __cpp_lib_format template _NODISCARD static string _Make_string(const local_time<_Duration>& _Tp, const local_info& _Info); #else // ^^^ no workaround / workaround vvv template _NODISCARD static string _Make_string(const local_time<_Duration>&, const local_info&) { return "ambiguous_local_time"; } #endif // ^^^ workaround ^^^ }; // [time.zone.timezone] enum class choose { earliest, latest }; class time_zone { public: explicit time_zone(string_view _Name_) : _Name(_Name_) {} time_zone(time_zone&&) = default; time_zone& operator=(time_zone&&) = default; _NODISCARD string_view name() const noexcept { return _Name; } template _NODISCARD sys_info get_info(const sys_time<_Duration>& _Sys) const { return _Get_info(_Sys.time_since_epoch()); } template _NODISCARD local_info get_info(const local_time<_Duration>& _Local) const { local_info _Info{}; const auto _Time_since_ep = _Local.time_since_epoch(); _Info.first = _Get_info(_Time_since_ep); const sys_seconds _Local_sys{_CHRONO duration_cast(_Time_since_ep)}; const auto _Curr_sys = _Local_sys - _Info.first.offset; if (_Info.first.begin != _Min_seconds && _Curr_sys < _Info.first.begin + days{1}) { // get previous transition information _Info.second = get_info(_Info.first.begin - seconds{1}); const auto _Transition = _Info.first.begin; const auto _Prev_sys = _Local_sys - _Info.second.offset; if (_Curr_sys >= _Transition) { if (_Prev_sys < _Transition) { _Info.result = local_info::ambiguous; _STD swap(_Info.first, _Info.second); } else { _Info.result = local_info::unique; _Info.second = {}; } } else { if (_Prev_sys >= _Transition) { _Info.result = local_info::nonexistent; _STD swap(_Info.first, _Info.second); } else { _Info.result = local_info::unique; _Info.first = _STD move(_Info.second); _Info.second = {}; } } } else if (_Info.first.end != _Max_seconds && _Curr_sys > _Info.first.end - days{1}) { // get next transition information _Info.second = get_info(_Info.first.end + seconds{1}); const auto _Transition = _Info.first.end; const auto _Next_sys = _Local_sys - _Info.second.offset; if (_Curr_sys < _Transition) { if (_Next_sys >= _Transition) { _Info.result = local_info::ambiguous; } else { _Info.result = local_info::unique; _Info.second = {}; } } else { if (_Next_sys < _Transition) { _Info.result = local_info::nonexistent; } else { _Info.result = local_info::unique; _Info.first = _STD move(_Info.second); _Info.second = {}; } } } else { // local time is contained inside of first transition boundaries by at least 1 day _Info.result = local_info::unique; _Info.second = {}; } return _Info; } template _NODISCARD sys_time> to_sys(const local_time<_Duration>& _Local) const { const auto _Info = get_info(_Local); if (_Info.result == local_info::nonexistent) { _THROW(nonexistent_local_time(_Local, _Info)); } else if (_Info.result == local_info::ambiguous) { _THROW(ambiguous_local_time(_Local, _Info)); } return sys_time>{_Local.time_since_epoch() - _Info.first.offset}; } template _NODISCARD sys_time> to_sys( const local_time<_Duration>& _Local, const choose _Choose) const { const auto _Info = get_info(_Local); if (_Info.result == local_info::nonexistent) { return _Info.first.end; } const auto _Offset = (_Info.result == local_info::unique || _Choose == choose::earliest) ? _Info.first.offset : _Info.second.offset; return sys_time>{_Local.time_since_epoch() - _Offset}; } template _NODISCARD local_time> to_local(const sys_time<_Duration>& _Sys) const { const auto _Info = get_info(_Sys); return local_time>{_Sys.time_since_epoch() + _Info.offset}; } static constexpr sys_seconds _Min_seconds{sys_days{(year::min) () / January / 1}}; static constexpr sys_seconds _Max_seconds{sys_seconds{sys_days{(year::max) () / December / 32}} - seconds{1}}; private: template _NODISCARD sys_info _Get_info(const _Duration& _Dur) const { using _Internal_duration = duration<__std_tzdb_epoch_milli, milli>; const auto _Internal_dur = _CHRONO duration_cast<_Internal_duration>(_Dur); const unique_ptr<__std_tzdb_sys_info, _Tzdb_deleter<__std_tzdb_sys_info>> _Info{ __std_tzdb_get_sys_info(_Name.c_str(), _Name.length(), _Internal_dur.count())}; if (_Info == nullptr) { _Xbad_alloc(); } else if (_Info->_Err == __std_tzdb_error::_Win_error) { _XGetLastError(); } else if (_Info->_Err == __std_tzdb_error::_Icu_error) { _Xruntime_error("Internal error loading IANA database information"); } constexpr auto _Min_internal = _CHRONO duration_cast<_Internal_duration>(_Min_seconds.time_since_epoch()).count(); constexpr auto _Max_internal = _CHRONO duration_cast<_Internal_duration>(_Max_seconds.time_since_epoch()).count(); const auto _Begin = _Info->_Begin <= _Min_internal ? _Min_seconds : sys_seconds{_CHRONO duration_cast(_Internal_duration{_Info->_Begin})}; const auto _End = _Info->_End >= _Max_internal ? _Max_seconds : sys_seconds{_CHRONO duration_cast(_Internal_duration{_Info->_End})}; return {.begin = _Begin, .end = _End, .offset = _CHRONO duration_cast(_Internal_duration{_Info->_Offset}), .save = _CHRONO duration_cast(_Internal_duration{_Info->_Save}), .abbrev = _Info->_Abbrev}; } string _Name; }; _NODISCARD inline bool operator==(const time_zone& _Left, const time_zone& _Right) noexcept { return _Left.name() == _Right.name(); } #ifdef __cpp_lib_concepts _NODISCARD inline strong_ordering operator<=>(const time_zone& _Left, const time_zone& _Right) noexcept { return _Left.name() <=> _Right.name(); } #endif // __cpp_lib_concepts // [time.zone.leap] class leap_second { public: leap_second(const leap_second&) = default; leap_second& operator=(const leap_second&) = default; constexpr leap_second( const sys_seconds& _Date_, const bool _Is_positive_, const seconds& _Prev_elapsed) noexcept : _Date{_Date_}, _Is_positive{_Is_positive_} { _Elapsed_offset = _Prev_elapsed + value(); } _NODISCARD constexpr sys_seconds date() const noexcept { return _Date; } _NODISCARD constexpr seconds value() const noexcept { return _Is_positive ? seconds{1} : seconds{-1}; } _NODISCARD constexpr bool _Positive() const noexcept { return _Is_positive; } _NODISCARD constexpr seconds _Elapsed() const noexcept { return _Elapsed_offset; } private: sys_seconds _Date; bool _Is_positive; seconds _Elapsed_offset; }; _NODISCARD constexpr bool operator==(const leap_second& _Left, const leap_second& _Right) noexcept { return _Left.date() == _Right.date(); } template _NODISCARD constexpr bool operator==(const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { return _Left.date() == _Right; } template _NODISCARD constexpr bool operator<(const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { return _Left.date() < _Right; } template _NODISCARD constexpr bool operator<(const sys_time<_Duration>& _Left, const leap_second& _Right) noexcept { return _Left < _Right.date(); } template _NODISCARD constexpr bool operator>(const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { return _Right < _Left.date(); } template _NODISCARD constexpr bool operator>(const sys_time<_Duration>& _Left, const leap_second& _Right) noexcept { return _Right.date() < _Left; } template _NODISCARD constexpr bool operator<=(const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { return !(_Right < _Left.date()); } template _NODISCARD constexpr bool operator<=(const sys_time<_Duration>& _Left, const leap_second& _Right) noexcept { return !(_Right.date() < _Left); } template _NODISCARD constexpr bool operator>=(const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { return !(_Left.date() < _Right); } template _NODISCARD constexpr bool operator>=(const sys_time<_Duration>& _Left, const leap_second& _Right) noexcept { return !(_Left < _Right.date()); } #ifdef __cpp_lib_concepts // clang-format off template requires three_way_comparable_with> _NODISCARD constexpr auto operator<=>( const leap_second& _Left, const sys_time<_Duration>& _Right) noexcept { // clang-format on return _Left.date() <=> _Right; } _NODISCARD constexpr strong_ordering operator<=>(const leap_second& _Left, const leap_second& _Right) noexcept { return _Left.date() <=> _Right.date(); } #endif // __cpp_lib_concepts // [time.zone.link] class time_zone_link { public: explicit time_zone_link(string_view _Name_, string_view _Target_) : _Name(_Name_), _Target(_Target_) {} time_zone_link(time_zone_link&&) = default; time_zone_link& operator=(time_zone_link&&) = default; _NODISCARD string_view name() const noexcept { return _Name; } _NODISCARD string_view target() const noexcept { return _Target; } private: string _Name; string _Target; }; _NODISCARD inline bool operator==(const time_zone_link& _Left, const time_zone_link& _Right) noexcept { return _Left.name() == _Right.name(); } #ifdef __cpp_lib_concepts _NODISCARD inline strong_ordering operator<=>(const time_zone_link& _Left, const time_zone_link& _Right) noexcept { return _Left.name() <=> _Right.name(); } #endif // __cpp_lib_concepts // [time.zone.db] _NODISCARD inline string _Tzdb_generate_current_zone() { unique_ptr<__std_tzdb_current_zone_info, _Tzdb_deleter<__std_tzdb_current_zone_info>> _Info{ __std_tzdb_get_current_zone()}; if (_Info == nullptr) { _Xbad_alloc(); } else if (_Info->_Err == __std_tzdb_error::_Win_error) { _XGetLastError(); } else if (_Info->_Err == __std_tzdb_error::_Icu_error) { _Xruntime_error("Internal error loading IANA database information"); } return {_Info->_Tz_name}; } template _NODISCARD const _Ty* _Locate_zone_impl(const vector<_Ty>& _Vec, string_view _Name) { const auto _Result = _STD find_if(_Vec.begin(), _Vec.end(), [&](auto& _Tz) { return _Tz.name() == _Name; }); return _Result == _Vec.end() ? nullptr : &*_Result; } struct tzdb { string version; vector zones; vector links; vector leap_seconds; bool _All_ls_positive; _NODISCARD const time_zone* locate_zone(string_view _Tz_name) const { auto _Tz = _Locate_zone_impl(zones, _Tz_name); if (_Tz != nullptr) { return _Tz; } const auto _Link = _Locate_zone_impl(links, _Tz_name); if (_Link != nullptr) { _Tz = _Locate_zone_impl(zones, _Link->target()); if (_Tz != nullptr) { return _Tz; } } _Xruntime_error("unable to locate time_zone with given name"); } _NODISCARD const time_zone* current_zone() const { return locate_zone(_Tzdb_generate_current_zone()); } }; _NODISCARD inline tuple _Tzdb_generate_time_zones() { unique_ptr<__std_tzdb_time_zones_info, _Tzdb_deleter<__std_tzdb_time_zones_info>> _Info{ __std_tzdb_get_time_zones()}; if (_Info == nullptr) { _Xbad_alloc(); } else if (_Info->_Err == __std_tzdb_error::_Win_error) { _XGetLastError(); } else if (_Info->_Err == __std_tzdb_error::_Icu_error) { _Xruntime_error("Internal error loading IANA database information"); } decltype(tzdb::zones) _Time_zones; decltype(tzdb::links) _Time_zone_links; for (size_t _Idx = 0; _Idx < _Info->_Num_time_zones; ++_Idx) { const string_view _Name{_Info->_Names[_Idx]}; if (_Info->_Links[_Idx] == nullptr) { _Time_zones.emplace_back(_Name); } else { const string_view _Target{_Info->_Links[_Idx]}; _Time_zone_links.emplace_back(_Name, _Target); } } return {_Info->_Version, _STD move(_Time_zones), _STD move(_Time_zone_links)}; } _NODISCARD inline pair _Tzdb_generate_leap_seconds(const size_t _Current_size) { // Returns empty vector if no new leap seconds are found. static constexpr leap_second _Known_leap_seconds[]{ {sys_seconds{seconds{78796800}}, true, seconds{0}}, {sys_seconds{seconds{94694400}}, true, seconds{1}}, {sys_seconds{seconds{126230400}}, true, seconds{2}}, {sys_seconds{seconds{157766400}}, true, seconds{3}}, {sys_seconds{seconds{189302400}}, true, seconds{4}}, {sys_seconds{seconds{220924800}}, true, seconds{5}}, {sys_seconds{seconds{252460800}}, true, seconds{6}}, {sys_seconds{seconds{283996800}}, true, seconds{7}}, {sys_seconds{seconds{315532800}}, true, seconds{8}}, {sys_seconds{seconds{362793600}}, true, seconds{9}}, {sys_seconds{seconds{394329600}}, true, seconds{10}}, {sys_seconds{seconds{425865600}}, true, seconds{11}}, {sys_seconds{seconds{489024000}}, true, seconds{12}}, {sys_seconds{seconds{567993600}}, true, seconds{13}}, {sys_seconds{seconds{631152000}}, true, seconds{14}}, {sys_seconds{seconds{662688000}}, true, seconds{15}}, {sys_seconds{seconds{709948800}}, true, seconds{16}}, {sys_seconds{seconds{741484800}}, true, seconds{17}}, {sys_seconds{seconds{773020800}}, true, seconds{18}}, {sys_seconds{seconds{820454400}}, true, seconds{19}}, {sys_seconds{seconds{867715200}}, true, seconds{20}}, {sys_seconds{seconds{915148800}}, true, seconds{21}}, {sys_seconds{seconds{1136073600}}, true, seconds{22}}, {sys_seconds{seconds{1230768000}}, true, seconds{23}}, {sys_seconds{seconds{1341100800}}, true, seconds{24}}, {sys_seconds{seconds{1435708800}}, true, seconds{25}}, {sys_seconds{seconds{1483228800}}, true, seconds{26}}, }; // __std_tzdb_get_leap_seconds gets leap second (LS) data from the registry, but only if it contains more // LSs than we already know about. The registry only contains LSs after 2018, so we need to tell it how many of // *those* we already know about. The *total* number of LSs known at this point is a combination of what the // caller knows (_Current_size, 0 on first call) and the _Known_leap_seconds entries. constexpr size_t _Pre_2018_count = 27; const size_t _Known_post_2018_ls_size = (_STD max) (_Current_size, _STD size(_Known_leap_seconds)) - _Pre_2018_count; size_t _Reg_post_2018_ls_size; // number of post-2018 LSs found in the registry unique_ptr<__std_tzdb_leap_info[], _Tzdb_deleter<__std_tzdb_leap_info[]>> _Reg_ls_data{ __std_tzdb_get_leap_seconds(_Known_post_2018_ls_size, &_Reg_post_2018_ls_size)}; if (_Reg_post_2018_ls_size > _Known_post_2018_ls_size && !_Reg_ls_data) { _Xbad_alloc(); // registry has new data, but failed to allocate storage } else if (_Reg_post_2018_ls_size == 0 && _Reg_ls_data) { _XGetLastError(); // allocated storage for registry data, but failed to read } const size_t _New_size = _Pre_2018_count + _Reg_post_2018_ls_size; // total size with registry data decltype(tzdb::leap_seconds) _Leap_sec_info; bool _All_ls_positive = true; if (_New_size > _Current_size) { _Leap_sec_info.reserve(_New_size); _Leap_sec_info.assign(_STD cbegin(_Known_leap_seconds), _STD cend(_Known_leap_seconds)); for (size_t _Idx = 0; _Idx < _Reg_post_2018_ls_size; ++_Idx) { // Leap seconds occur at _Ls._Hour:59:59. We store the next second after, so we need to add an entire // hour. const auto& _Ls = _Reg_ls_data[_Idx]; const auto _Date = static_cast(year_month_day{year{_Ls._Year}, month{_Ls._Month}, day{_Ls._Day}}) + hours{_Ls._Hour + 1}; _Leap_sec_info.emplace_back(_Date, !_Ls._Negative, _Leap_sec_info.back()._Elapsed()); _All_ls_positive = _All_ls_positive && !_Ls._Negative; } } return {_STD move(_Leap_sec_info), _All_ls_positive}; } _NODISCARD inline string _Tzdb_update_version(const string_view _Version, const size_t _Num_leap_seconds) { string _Icu_version{_Version.substr(0, _Version.find_last_of('.'))}; return _STD move(_Icu_version) + "." + _STD to_string(_Num_leap_seconds); } class tzdb_list { private: using _ListType = forward_list>; public: using const_iterator = _ListType::const_iterator; tzdb_list(const tzdb_list&) = delete; tzdb_list& operator=(const tzdb_list&) = delete; tzdb_list() { auto [_Icu_version, _Zones, _Links] = _Tzdb_generate_time_zones(); auto [_Leap_sec, _All_ls_positive] = _Tzdb_generate_leap_seconds(0); auto _Version = _Icu_version + "." + _STD to_string(_Leap_sec.size()); _Tzdb_list.emplace_front(tzdb{ _STD move(_Version), _STD move(_Zones), _STD move(_Links), _STD move(_Leap_sec), _All_ls_positive}); } _NODISCARD const tzdb& front() const noexcept { _Shared_lock _Lk(_Tzdb_mutex); return _Tzdb_list.front(); } const_iterator erase_after(const_iterator _Where) noexcept /* strengthened */ { _Unique_lock _Lk(_Tzdb_mutex); return _Tzdb_list.erase_after(_Where); } _NODISCARD const_iterator begin() const noexcept { _Shared_lock _Lk(_Tzdb_mutex); return _Tzdb_list.begin(); } _NODISCARD const_iterator end() const noexcept { return _Tzdb_list.end(); // no lock necessary for forward_list::end() } _NODISCARD const_iterator cbegin() const noexcept { _Shared_lock _Lk(_Tzdb_mutex); return _Tzdb_list.cbegin(); } _NODISCARD const_iterator cend() const noexcept { return _Tzdb_list.cend(); // no lock necessary for forward_list::cend() } template void _Emplace_front(_ArgsTy&&... _Args) { _Unique_lock _Lk(_Tzdb_mutex); _Tzdb_list.emplace_front(_STD forward<_ArgsTy>(_Args)...); } const tzdb& _Reload() { _Unique_lock _Lk(_Tzdb_mutex); auto [_Leap_sec, _All_ls_positive] = _Tzdb_generate_leap_seconds(_Tzdb_list.front().leap_seconds.size()); if (!_Leap_sec.empty()) { const auto& _Tzdb = _Tzdb_list.front(); vector _Zones; _STD transform(_Tzdb.zones.begin(), _Tzdb.zones.end(), _STD back_inserter(_Zones), [](const auto& _Tz) { return time_zone{_Tz.name()}; }); vector _Links; _STD transform( _Tzdb.links.begin(), _Tzdb.links.end(), _STD back_inserter(_Links), [](const auto& _Link) { return time_zone_link{_Link.name(), _Link.target()}; }); auto _Version = _Tzdb_update_version(_Tzdb.version, _Leap_sec.size()); _Tzdb_list.emplace_front(tzdb{ _STD move(_Version), _STD move(_Zones), _STD move(_Links), _STD move(_Leap_sec), _All_ls_positive}); } return _Tzdb_list.front(); } private: _ListType _Tzdb_list; mutable _Smtx_t _Tzdb_mutex = {}; struct _NODISCARD _Shared_lock { explicit _Shared_lock(_Smtx_t& _Mtx_) : _Mtx{&_Mtx_} { _Smtx_lock_shared(_Mtx); } _Shared_lock(const _Shared_lock&) = delete; _Shared_lock& operator=(const _Shared_lock&) = delete; ~_Shared_lock() { _Smtx_unlock_shared(_Mtx); } _Smtx_t* _Mtx; }; struct _NODISCARD _Unique_lock { explicit _Unique_lock(_Smtx_t& _Mtx_) : _Mtx{&_Mtx_} { _Smtx_lock_exclusive(_Mtx); } _Unique_lock(const _Unique_lock&) = delete; _Unique_lock& operator=(const _Unique_lock&) = delete; ~_Unique_lock() { _Smtx_unlock_exclusive(_Mtx); } _Smtx_t* _Mtx; }; }; inline atomic _Global_tzdb_list; _NODISCARD inline tzdb_list& get_tzdb_list() { auto* _Tzdb_ptr = _Global_tzdb_list.load(); if (_Tzdb_ptr != nullptr) { return *_Tzdb_ptr; } auto _My_tzdb = static_cast(__std_calloc_crt(1, sizeof(tzdb_list))); if (_My_tzdb == nullptr) { _Xruntime_error("bad allocation"); // not bad_alloc, see N4878 [time.zone.db.access]/4 } _TRY_BEGIN _STD construct_at(_My_tzdb); _CATCH(const runtime_error&) __std_free_crt(_My_tzdb); _RERAISE; _CATCH(const exception& _Except) #if _HAS_EXCEPTIONS __std_free_crt(_My_tzdb); _Xruntime_error(_Except.what()); #endif // _HAS_EXCEPTIONS _CATCH_END if (_Global_tzdb_list.compare_exchange_strong(_Tzdb_ptr, _My_tzdb)) { _Tzdb_ptr = _My_tzdb; } else { _STD destroy_at(_My_tzdb); __std_free_crt(_My_tzdb); } return *_Tzdb_ptr; } _NODISCARD inline const tzdb& get_tzdb() { return _CHRONO get_tzdb_list().front(); } _NODISCARD inline const time_zone* locate_zone(string_view _Tz_name) { return _CHRONO get_tzdb().locate_zone(_Tz_name); } _NODISCARD inline const time_zone* current_zone() { return _CHRONO get_tzdb().current_zone(); } inline const tzdb& reload_tzdb() { _TRY_BEGIN return _CHRONO get_tzdb_list()._Reload(); _CATCH(const runtime_error&) _RERAISE; _CATCH(const exception& _Except) #if _HAS_EXCEPTIONS _Xruntime_error(_Except.what()); #endif // _HAS_EXCEPTIONS _CATCH_END } _NODISCARD inline string remote_version() { const auto& _Tzdb = _CHRONO get_tzdb(); const auto& _Version = _Tzdb.version; const auto [_Leap_sec, _Ignored] = _Tzdb_generate_leap_seconds(_Tzdb.leap_seconds.size()); return _Leap_sec.empty() ? _Version : _Tzdb_update_version(_Version, _Leap_sec.size()); } // [time.zone.zonedtraits] template struct zoned_traits {}; template <> struct zoned_traits { _NODISCARD static const time_zone* default_zone() { return _CHRONO get_tzdb().locate_zone("UTC"); } _NODISCARD static const time_zone* locate_zone(string_view _Name) { return _CHRONO get_tzdb().locate_zone(_Name); } }; // [time.zone.zonedtime] template class zoned_time { private: static_assert(_Is_duration_v<_Duration>, "N4885 [time.zone.zonedtime.overview]/2 mandates Duration to be a specialization of chrono::duration."); using _Traits = zoned_traits<_TimeZonePtr>; public: using duration = common_type_t<_Duration, seconds>; template > zoned_time() : _Zone{_Traits::default_zone()} {} zoned_time(const zoned_time&) = default; zoned_time& operator=(const zoned_time&) = default; template > zoned_time(const sys_time<_Duration>& _Sys) : _Zone{_Traits::default_zone()}, _Tp{_Sys} {} explicit zoned_time(_TimeZonePtr _Tz) noexcept /* strengthened */ : _Zone{_STD move(_Tz)} {} // clang-format off template , int> = 0> // clang-format on explicit zoned_time(string_view _Name) : _Zone{_Traits::locate_zone(_Name)} {} template , sys_time<_Duration>>, int> = 0> zoned_time(const zoned_time<_Duration2, _TimeZonePtr>& _Zt) noexcept /* strengthened */ : _Zone{_Zt.get_time_zone()}, _Tp{_Zt.get_sys_time()} {} zoned_time(_TimeZonePtr _Tz, const sys_time<_Duration>& _Sys) : _Zone{_STD move(_Tz)}, _Tp{_Sys} {} // clang-format off template &>, int> = 0> // clang-format on zoned_time(string_view _Name, type_identity_t&> _Sys) : zoned_time{_Traits::locate_zone(_Name), _Sys} {} template ()->to_sys(local_time<_Duration>{})), sys_time>, int> = 0> zoned_time(_TimeZonePtr _Tz, const local_time<_Duration>& _Local) : _Zone{_STD move(_Tz)}, _Tp{_Zone->to_sys(_Local)} {} // clang-format off template &>, int> = 0> // clang-format on zoned_time(string_view _Name, type_identity_t>& _Local) : zoned_time{_Traits::locate_zone(_Name), _Local} {} template ()->to_sys(local_time<_Duration>{}, choose::earliest)), sys_time>, int> = 0> zoned_time(_TimeZonePtr _Tz, const local_time<_Duration>& _Local, choose _Choose) : _Zone{_STD move(_Tz)}, _Tp{_Zone->to_sys(_Local, _Choose)} {} // clang-format off template &, choose>, int> = 0> // clang-format on zoned_time(string_view _Name, type_identity_t&> _Local, choose _Choose) : zoned_time{_Traits::locate_zone(_Name), _Local, _Choose} {} template , sys_time<_Duration>>, int> = 0> zoned_time(_TimeZonePtr _Tz, const zoned_time<_Duration2, _TimeZonePtr2>& _Zt) noexcept /* strengthened */ : _Zone{_STD move(_Tz)}, _Tp{_Zt.get_sys_time()} {} template , sys_time<_Duration>>, int> = 0> zoned_time( _TimeZonePtr _Tz, const zoned_time<_Duration2, _TimeZonePtr2>& _Zt, choose) noexcept /* strengthened */ : zoned_time{_Tz, _Zt} {} // clang-format off template &>, int> = 0> // clang-format on zoned_time(string_view _Name, const zoned_time<_Duration2, _TimeZonePtr2>& _Zt) : zoned_time{_Traits::locate_zone(_Name), _Zt} {} // clang-format off template &, choose>, int> = 0> // clang-format on zoned_time(string_view _Name, const zoned_time<_Duration2, _TimeZonePtr2>& _Zt, choose _Choose) : zoned_time{_Traits::locate_zone(_Name), _Zt, _Choose} {} zoned_time& operator=(const sys_time<_Duration>& _Sys) noexcept /* strengthened */ { _Tp = _Sys; return *this; } zoned_time& operator=(const local_time<_Duration>& _Local) { _Tp = _Zone->to_sys(_Local); return *this; } operator sys_time() const noexcept /* strengthened */ { return get_sys_time(); } explicit operator local_time() const { return get_local_time(); } _NODISCARD _TimeZonePtr get_time_zone() const noexcept /* strengthened */ { return _Zone; } _NODISCARD local_time get_local_time() const { return _Zone->to_local(_Tp); } _NODISCARD sys_time get_sys_time() const noexcept /* strengthened */ { return _Tp; } _NODISCARD sys_info get_info() const { return _Zone->get_info(_Tp); } private: _TimeZonePtr _Zone; sys_time _Tp{}; }; zoned_time()->zoned_time; template zoned_time(sys_time<_Duration>) -> zoned_time>; template using _Time_zone_representation = conditional_t, const time_zone*, remove_cvref_t<_TimeZonePtrOrName>>; template zoned_time(_TimeZonePtrOrName&&) -> zoned_time>; template zoned_time(_TimeZonePtrOrName&&, sys_time<_Duration>) -> zoned_time, _Time_zone_representation<_TimeZonePtrOrName>>; template zoned_time(_TimeZonePtrOrName&&, local_time<_Duration>, choose = choose::earliest) -> zoned_time, _Time_zone_representation<_TimeZonePtrOrName>>; template zoned_time(_TimeZonePtrOrName&&, zoned_time<_Duration, _TimeZonePtr2>, choose = choose::earliest) -> zoned_time, _Time_zone_representation<_TimeZonePtrOrName>>; using zoned_seconds = zoned_time; template _NODISCARD bool operator==( const zoned_time<_Duration1, _TimeZonePtr>& _Left, const zoned_time<_Duration2, _TimeZonePtr>& _Right) { return _Left.get_time_zone() == _Right.get_time_zone() && _Left.get_sys_time() == _Right.get_sys_time(); } // [time.clock.utc] class utc_clock; template using utc_time = time_point; using utc_seconds = utc_time; struct leap_second_info { bool is_leap_second; seconds elapsed; }; template _NODISCARD leap_second_info get_leap_second_info(const utc_time<_Duration>& _Time) { const utc_seconds _Time_floor = _CHRONO floor(_Time); const auto& _Tzdb = _CHRONO get_tzdb(); const auto& _Ls_vector = _Tzdb.leap_seconds; // Find first leap second after _Time. vector::const_iterator _It; if (_Tzdb._All_ls_positive) { // Where "target_ls" is the next leap second at or after _Time, _It either points to: // (1) The 2nd leap second after _Time if _Time_floor is in the range [target_ls - _Elapsed() - 1, // target_ls), or // (2) The leap second just after _Time otherwise. // Note that we can always use prev(_It) to determine whether _Time is *during* a leap second insertion, // since that falls under case (2) above. However, when we fall under case (1), we need to execute an // additional decrement to get the correct elapsed offset. For example, if leap seconds are inserted at // seconds {100, 200, 300, 400}, we have: // // UTC sys *_It // 99 99 100 // 100 X 200 // 101 100 200 // 102 101 200 // ... // 199 198 200 // 200 199 300^ // 201 X 300 // 202 200 300 // ... // 299 297 300 // 300 298 400^ // 301 299 400^ // 302 X 400 // 303 300 400 // // ^_It points to 2nd leap second _It = _STD upper_bound(_Ls_vector.begin(), _Ls_vector.end(), sys_seconds{_Time_floor.time_since_epoch()}); } else { seconds _Prev_elapsed{0}; for (_It = _Ls_vector.begin(); _It != _Ls_vector.end(); ++_It) { // UTC time when leap second insertion begins. In all cases, _It->date() + _It->_Elapsed() is the *end* // of the insertion. For a negative leap that's also the beginning, but for a positive one, insertion // begins 1 second earlier. const utc_seconds _This_ls_begin{ _It->date().time_since_epoch() + (_It->_Positive() ? _Prev_elapsed : _It->_Elapsed())}; if (_This_ls_begin > _Time_floor) { break; } _Prev_elapsed = _It->_Elapsed(); } } if (_It == _Ls_vector.begin()) { return {false, seconds{0}}; } else { // Convert to the last leap second before or equal to _Time. const auto& _Last_leap = *--_It; const utc_seconds _Utc_leap_second{_Last_leap.date().time_since_epoch() + _It->_Elapsed() - seconds{1}}; #ifdef __cpp_lib_concepts const auto _Leap_cmp = _Utc_leap_second <=> _Time_floor; #else // ^^^ __cpp_lib_concepts / TRANSITION, GH-395 workaround vvv const auto _Leap_cmp = _Utc_leap_second > _Time_floor ? strong_ordering::greater : _Utc_leap_second == _Time_floor ? strong_ordering::equal : strong_ordering::less; #endif // ^^^ workaround if (_Tzdb._All_ls_positive && _STD is_gt(_Leap_cmp)) { // Case (1) --_It; } return {_Last_leap._Positive() && _STD is_eq(_Leap_cmp), _It->_Elapsed()}; } } class utc_clock { public: using rep = system_clock::rep; using period = system_clock::period; using duration = _CHRONO duration; using time_point = _CHRONO time_point; static constexpr bool is_steady = system_clock::is_steady; _NODISCARD static time_point now() { return from_sys(system_clock::now()); } template _NODISCARD static sys_time> to_sys(const utc_time<_Duration>& _Utc_time) { using _CommonType = common_type_t<_Duration, seconds>; const auto _Lsi{_CHRONO get_leap_second_info(_Utc_time)}; _CommonType _Ticks; if (_Lsi.is_leap_second) { const auto _Leap_sec_minus_one = _CHRONO floor(_Utc_time.time_since_epoch()) - _Lsi.elapsed; if constexpr (is_integral_v) { constexpr auto _Delta{seconds{1} - _CommonType{1}}; _Ticks = _Leap_sec_minus_one + _Delta; } else { const auto _Leap_sec_begin = _CHRONO ceil<_CommonType>(_Leap_sec_minus_one + seconds{1}); _Ticks = _CommonType{_STD nextafter(_Leap_sec_begin.count(), typename _CommonType::rep{0})}; } } else { _Ticks = _Utc_time.time_since_epoch() - _Lsi.elapsed; } return sys_time<_CommonType>{_Ticks}; } template _NODISCARD static utc_time> from_sys(const sys_time<_Duration>& _Sys_time) { const auto& _Tzdb = _CHRONO get_tzdb(); const auto& _Ls_vector = _Tzdb.leap_seconds; auto _It = _STD upper_bound(_Ls_vector.begin(), _Ls_vector.end(), _CHRONO floor(_Sys_time)); const auto _Offset = _It == _Ls_vector.begin() ? seconds{0} : (--_It)->_Elapsed(); return utc_time>{_Sys_time.time_since_epoch() + _Offset}; } }; // [time.clock.tai] class tai_clock; template using tai_time = time_point; using tai_seconds = tai_time; class tai_clock { public: using rep = system_clock::rep; using period = system_clock::period; using duration = _CHRONO duration; using time_point = _CHRONO time_point; static constexpr bool is_steady = system_clock::is_steady; static constexpr seconds _Tai_epoch_adjust{378691210}; _NODISCARD static time_point now() { return from_utc(utc_clock::now()); } template _NODISCARD static utc_time> to_utc( const tai_time<_Duration>& _Time) noexcept { return utc_time>{_Time.time_since_epoch()} - _Tai_epoch_adjust; } template _NODISCARD static tai_time> from_utc( const utc_time<_Duration>& _Time) noexcept { return tai_time>{_Time.time_since_epoch()} + _Tai_epoch_adjust; } }; // [time.clock.gps] class gps_clock; template using gps_time = time_point; using gps_seconds = gps_time; class gps_clock { public: using rep = system_clock::rep; using period = system_clock::period; using duration = _CHRONO duration; using time_point = _CHRONO time_point; static constexpr bool is_steady = system_clock::is_steady; static constexpr seconds _Gps_epoch_adjust{-315964809}; _NODISCARD static time_point now() { return from_utc(utc_clock::now()); } template _NODISCARD static utc_time> to_utc( const gps_time<_Duration>& _Time) noexcept { return utc_time>{_Time.time_since_epoch()} - _Gps_epoch_adjust; } template _NODISCARD static gps_time> from_utc( const utc_time<_Duration>& _Time) noexcept { return gps_time>{_Time.time_since_epoch()} + _Gps_epoch_adjust; } }; #endif // ^^^ _HAS_CXX20 } // namespace chrono // [time.clock.file] #if _HAS_CXX20 namespace filesystem { struct _File_time_clock; } // namespace filesystem namespace chrono { using file_clock = filesystem::_File_time_clock; template using file_time = time_point; } // namespace chrono #endif // ^^^ _HAS_CXX20 #if _HAS_CXX17 namespace filesystem { inline constexpr long long __std_fs_file_time_epoch_adjustment = 0x19DB1DED53E8000LL; // TRANSITION, ABI struct _File_time_clock { // Implementation of trivial-clock using rep = long long; using period = chrono::system_clock::period; using duration = chrono::duration; using time_point = chrono::time_point<_File_time_clock>; static constexpr bool is_steady = false; _NODISCARD static time_point now() noexcept { // get current time; undo epoch adjustment return time_point(duration(_Xtime_get_ticks() + __std_fs_file_time_epoch_adjustment)); // TRANSITION, ABI } #if _HAS_CXX20 // Assumes that FILETIME counts leap seconds only after the first 27 (i.e., after 1 January 2017), even though // systems can opt out of this behavior. static constexpr chrono::seconds _Skipped_filetime_leap_seconds{27}; static constexpr chrono::sys_days _Cutoff{ chrono::year_month_day{chrono::year{2017}, chrono::January, chrono::day{1}}}; template _NODISCARD static chrono::utc_time> to_utc( const chrono::file_time<_Duration>& _File_time) { using namespace chrono; using _CommonType = common_type_t<_Duration, seconds>; const auto _Ticks = _File_time.time_since_epoch() - _CHRONO duration_cast(duration{__std_fs_file_time_epoch_adjustment}); if (_Ticks < _Cutoff.time_since_epoch()) { return utc_clock::from_sys(sys_time<_CommonType>{_Ticks}); } else { return utc_time<_CommonType>{_Ticks + _Skipped_filetime_leap_seconds}; } } template _NODISCARD static chrono::file_time> from_utc( const chrono::utc_time<_Duration>& _Utc_time) { using namespace chrono; file_time> _File_time{ _CHRONO duration_cast(duration{__std_fs_file_time_epoch_adjustment})}; if (_Utc_time < utc_seconds{_Cutoff.time_since_epoch()} + _Skipped_filetime_leap_seconds) { _File_time += utc_clock::to_sys(_Utc_time).time_since_epoch(); } else { _File_time += _Utc_time.time_since_epoch() - _Skipped_filetime_leap_seconds; } return _File_time; } #endif // ^^^ _HAS_CXX20 }; } // namespace filesystem #endif // ^^^ _HAS_CXX17 namespace chrono { #if _HAS_CXX20 // [time.clock.conv] template struct clock_time_conversion {}; // [time.clock.cast.id] template struct clock_time_conversion<_Clock, _Clock> { template _NODISCARD time_point<_Clock, _Duration> operator()(const time_point<_Clock, _Duration>& _Time) const noexcept(is_arithmetic_v) /* strengthened */ { return _Time; } }; template <> struct clock_time_conversion { template _NODISCARD sys_time<_Duration> operator()(const sys_time<_Duration>& _Time) const noexcept(is_arithmetic_v) /* strengthened */ { return _Time; } }; template <> struct clock_time_conversion { template _NODISCARD utc_time<_Duration> operator()(const utc_time<_Duration>& _Time) const noexcept(is_arithmetic_v) /* strengthened */ { return _Time; } }; // [time.clock.cast.sys.utc] template <> struct clock_time_conversion { template _NODISCARD utc_time> operator()(const sys_time<_Duration>& _Sys_time) const { return utc_clock::from_sys(_Sys_time); } }; template <> struct clock_time_conversion { template _NODISCARD sys_time> operator()(const utc_time<_Duration>& _Utc_time) const { return utc_clock::to_sys(_Utc_time); } }; // [time.clock.cast.sys] template inline constexpr bool _Is_time_point_for_clock = false; template inline constexpr bool _Is_time_point_for_clock, _Clock> = true; template struct clock_time_conversion { template &>()))>> _NODISCARD auto operator()(const time_point<_SourceClock, _Duration>& _Time) const noexcept(noexcept(_SourceClock::to_sys(_Time))) /* strengthened */ { static_assert(_Is_time_point_for_clock, "N4885 [time.clock.cast.sys]/2: Mandates: SourceClock::to_sys(t) returns a sys_time"); return _SourceClock::to_sys(_Time); } }; template struct clock_time_conversion<_DestClock, system_clock> { template &>()))>> _NODISCARD auto operator()(const sys_time<_Duration>& _Time) const noexcept(noexcept(_DestClock::from_sys(_Time))) /* strengthened */ { static_assert(_Is_time_point_for_clock, "N4885 [time.clock.cast.sys]/5: Mandates: DestClock::from_sys(t) returns a " "time_point"); return _DestClock::from_sys(_Time); } }; // [time.clock.cast.utc] template struct clock_time_conversion { template &>()))>> _NODISCARD auto operator()(const time_point<_SourceClock, _Duration>& _Time) const noexcept(noexcept(_SourceClock::to_utc(_Time))) /* strengthened */ { static_assert(_Is_time_point_for_clock, "N4885 [time.clock.cast.utc]/2: Mandates: SourceClock::to_utc(t) returns a utc_time"); return _SourceClock::to_utc(_Time); } }; template struct clock_time_conversion<_DestClock, utc_clock> { template &>()))>> _NODISCARD auto operator()(const utc_time<_Duration>& _Time) const noexcept(noexcept(_DestClock::from_utc(_Time))) /* strengthened */ { static_assert(_Is_time_point_for_clock, "N4885 [time.clock.cast.utc]/5: Mandates: DestClock::from_utc(t) returns a " "time_point"); return _DestClock::from_utc(_Time); } }; // [time.clock.cast.fn] enum class _Clock_cast_strategy { _Direct, _Via_sys, _Via_utc, _Via_utc_from_sys, _Via_sys_from_utc, _Two_step_ambiguous, _Three_step_ambiguous, _None, }; template inline constexpr bool _Has_two_step_conversion = false; template inline constexpr bool _Has_two_step_conversion<_Conv1, _Conv2, _Tp, void_t())))>> = true; template inline constexpr bool _Has_three_step_conversion = false; template inline constexpr bool _Has_three_step_conversion<_Conv1, _Conv2, _Conv3, _Tp, void_t()))))>> = true; template _NODISCARD _CONSTEVAL _Clock_cast_strategy _Choose_clock_cast() noexcept { using _Tp = const time_point<_SourceClock, _Duration>&; if constexpr (is_invocable_v, _Tp>) { return _Clock_cast_strategy::_Direct; } else { constexpr bool _Has_sys = _Has_two_step_conversion< // clock_time_conversion<_DestClock, system_clock>, // clock_time_conversion, _Tp>; constexpr bool _Has_utc = _Has_two_step_conversion< // clock_time_conversion<_DestClock, utc_clock>, // clock_time_conversion, _Tp>; if constexpr (_Has_sys && _Has_utc) { return _Clock_cast_strategy::_Two_step_ambiguous; } else if constexpr (_Has_sys) { return _Clock_cast_strategy::_Via_sys; } else if constexpr (_Has_utc) { return _Clock_cast_strategy::_Via_utc; } else { constexpr bool _Has_utc_from_sys = _Has_three_step_conversion< // clock_time_conversion<_DestClock, utc_clock>, // clock_time_conversion, // clock_time_conversion, _Tp>; constexpr bool _Has_sys_from_utc = _Has_three_step_conversion< // clock_time_conversion<_DestClock, system_clock>, // clock_time_conversion, // clock_time_conversion, _Tp>; if constexpr (_Has_utc_from_sys && _Has_sys_from_utc) { return _Clock_cast_strategy::_Three_step_ambiguous; } else if constexpr (_Has_utc_from_sys) { return _Clock_cast_strategy::_Via_utc_from_sys; } else if constexpr (_Has_sys_from_utc) { return _Clock_cast_strategy::_Via_sys_from_utc; } else { return _Clock_cast_strategy::_None; } } } } template inline constexpr auto _Clock_cast_choice = _Choose_clock_cast<_DestClock, _SourceClock, _Duration>(); template != _Clock_cast_strategy::_None, int> = 0> _NODISCARD auto clock_cast(const time_point<_SourceClock, _Duration>& _Time) { constexpr auto _Strat = _Clock_cast_choice<_DestClock, _SourceClock, _Duration>; if constexpr (_Strat == _Clock_cast_strategy::_Direct) { return clock_time_conversion<_DestClock, _SourceClock>{}(_Time); } else if constexpr (_Strat == _Clock_cast_strategy::_Via_sys) { return clock_time_conversion<_DestClock, system_clock>{}( clock_time_conversion{}(_Time)); } else if constexpr (_Strat == _Clock_cast_strategy::_Via_utc) { return clock_time_conversion<_DestClock, utc_clock>{}( clock_time_conversion{}(_Time)); } else if constexpr (_Strat == _Clock_cast_strategy::_Via_utc_from_sys) { return clock_time_conversion<_DestClock, utc_clock>{}( // clock_time_conversion{}( clock_time_conversion{}(_Time))); } else if constexpr (_Strat == _Clock_cast_strategy::_Via_sys_from_utc) { return clock_time_conversion<_DestClock, system_clock>{}( // clock_time_conversion{}( clock_time_conversion{}(_Time))); } else if constexpr (_Strat == _Clock_cast_strategy::_Two_step_ambiguous) { static_assert(_Always_false<_Duration>, "A two-step clock time conversion is required to be unique, " "either through utc_clock or system_clock, but not both (N4878 [time.clock.cast.fn]/2)."); } else if constexpr (_Strat == _Clock_cast_strategy::_Three_step_ambiguous) { static_assert(_Always_false<_Duration>, "A three-step clock time conversion is required to be unique, " "either utc-to-system or system-to-utc, but not both (N4878 [time.clock.cast.fn]/2)."); } else { static_assert(_Always_false<_Duration>, "should be unreachable"); } } // [time.parse] struct _Time_parse_fields { using _SubsecondType = duration; // These are the primary fields, used to set the chrono type being parsed. optional _Subsecond; optional _Second; optional _Minute; optional _Hour_24; optional _Weekday; // 0-based, starts Sunday optional _Day; // 1-based optional _Month; // 1-based optional _Day_of_year; // 1-based optional _Two_dig_year; optional _Century; optional _Utc_offset; // in minutes optional _Tz_name; // These are the secondary fields, used to store parsed data. They must be converted to primary fields and // checked for consistency. optional _Hour_12; optional _Ampm; optional _Iso_year; optional _Two_dig_iso_year; optional _Iso_week; // 1-based optional _Week_u; // week number, W01 begins on first Sunday optional _Week_w; // week number, W01 begins on first Monday enum _FieldFlags : unsigned int { _F_sec = 0x01, _F_min = 0x02, _F_hr = 0x04, _F_day = 0x08, _F_wkday = 0x10, _F_mon = 0x20, _F_doy = 0x40, _F_year = 0x80, }; _NODISCARD unsigned int _Used_fields() const { unsigned int _Ret{0}; if (_Second || _Subsecond) { _Ret |= _F_sec; } if (_Minute) { _Ret |= _F_min; } if (_Hour_24) { _Ret |= _F_hr; } if (_Day) { _Ret |= _F_day; } if (_Weekday) { _Ret |= _F_wkday; } if (_Month) { _Ret |= _F_mon; } if (_Day_of_year) { _Ret |= _F_doy; } if (_Two_dig_year && _Century) { _Ret |= _F_year; } return _Ret; } _NODISCARD static bool _Test_bits( const unsigned int _Bits, const unsigned int _Must_set, const unsigned int _Optional = 0) { return (_Bits & ~_Optional) == _Must_set; } template static constexpr _Ty _Invalid_time_field{numeric_limits<_Ty>::lowest()}; static void _Initialize_time_point(tm& _Tp) { _Tp.tm_sec = _Invalid_time_field; _Tp.tm_min = _Invalid_time_field; _Tp.tm_hour = _Invalid_time_field; _Tp.tm_wday = _Invalid_time_field; _Tp.tm_mday = _Invalid_time_field; _Tp.tm_mon = _Invalid_time_field; _Tp.tm_yday = _Invalid_time_field; _Tp.tm_year = _Invalid_time_field; } template _NODISCARD static bool _Update(optional<_Ty>& _Val, const _Ty& _New) { // Update a field. Ignores invalid values. If _Val already has a value, returns true or false according to // whether the new value matches the current one or not, so that inconsistencies can be detected. if constexpr (!is_same_v<_Ty, string>) { if (_New == _Invalid_time_field<_Ty>) { return true; } } if (!_Val.has_value()) { _Val = _New; return true; } else { return _STD exchange(_Val, _New) == _New; } } _NODISCARD static pair _Decompose_year(const int _Year) { int _Two_d_year = _Year % 100; if (_Two_d_year < 0) { _Two_d_year += 100; } return {_Year - _Two_d_year, _Two_d_year}; } _NODISCARD bool _Update_if_valid(const tm& _Tp, const bool _Full_year) { bool _No_err{true}; if (_Tp.tm_hour != _Invalid_time_field) { _No_err = _No_err && _Update(_Hour_24, _Tp.tm_hour); _No_err = _No_err && _Update(_Ampm, _Hour_24 >= 12 ? 1 : 0); _No_err = _No_err && _Update(_Hour_12, _CHRONO make12(hours{*_Hour_24}).count()); } _No_err = _No_err && _Update(_Minute, _Tp.tm_min); _No_err = _No_err && _Update(_Second, _Tp.tm_sec); _No_err = _No_err && _Update(_Day, _Tp.tm_mday); _No_err = _No_err && _Update(_Weekday, _Tp.tm_wday); if (_Tp.tm_mon != _Invalid_time_field) { _No_err = _No_err && _Update(_Month, _Tp.tm_mon + 1); } if (_Tp.tm_yday != _Invalid_time_field) { _No_err = _No_err && _Update(_Day_of_year, _Tp.tm_yday + 1); } if (_Tp.tm_year != _Invalid_time_field) { // Sometimes we expect only the last two digits. const auto _Year_parts = _Decompose_year(_Tp.tm_year + 1900); _No_err = _No_err && _Update(_Two_dig_year, _Year_parts.second); if (_Full_year) { _No_err = _No_err && _Update(_Century, _Year_parts.first); } } return _No_err; } _NODISCARD bool _Yday_to_month_day(const int _Yday, const int _Year) { // A day-of-year that's February 28 or earlier, by itself, is a valid month_day. Any later day is // ambiguous without a year. if (_Out_of_range(_Day_of_year, 1, _Two_dig_year || _Iso_year ? _Days_in_year(_Year) : 59)) { return false; } if (_Day_of_year <= 31) { return _Update(_Day, _Yday) && _Update(_Month, 1); } const int _Feb_end{_Is_leap(_Year) ? 60 : 59}; if (_Day_of_year <= _Feb_end) { return _Update(_Day, _Yday - 31) && _Update(_Month, 2); } // Shift day-of-year so that 1 == March 1. This is the same as year_month_day::_Civil_from_days, except // _Day_of_year --> _Shifted_yday-1 and _Mp --> _Month - 3. const int _Shifted_yday{*_Day_of_year - _Feb_end}; return _Update(_Month, (535 * _Shifted_yday + 48950) >> 14) && _Update(_Day, _Shifted_yday - ((979 * *_Month - 2918) >> 5)); } static constexpr int _Era_begin_wday{3}; // Wednesday _NODISCARD static constexpr int _Jan1_weekday(int _Year) { --_Year; const int _Era = (_Year >= 0 ? _Year : _Year - 399) / 400; const int _Yoe = _Year - _Era * 400; // Jan. 1 is always day 306 of the shifted [Mar, ..., Dec, Jan, Feb] year. const int _Doe = ((1461 * _Yoe) >> 2) - _Yoe / 100 + 306; return (_Doe + _Era_begin_wday) % 7; } _NODISCARD static constexpr int _Iso8601_weeks(int _Year) { const int _P_y = (_Year + _Year / 4 - _Year / 100 + _Year / 400) % 7; --_Year; const int _P_ym1 = (_Year + _Year / 4 - _Year / 100 + _Year / 400) % 7; return 52 + (_P_y == 4 || _P_ym1 == 3); } _NODISCARD static constexpr int _Iso8601_week(const int _Day_of_year, const int _Weekday, const int _Year) { // Jan. 4 is always week 1; rollover to next week always happens on Monday. const auto _Week{(_Day_of_year + 9 - _Prev_weekday(_Weekday, 1)) / 7}; if (_Week < 1) { return _Iso8601_weeks(_Year - 1); } else if (_Week > _Iso8601_weeks(_Year)) { return 1; } else { return _Week; } } _NODISCARD static constexpr bool _Is_leap(const int _Year) { return _Year % 4 == 0 && (_Year % 100 != 0 || _Year % 400 == 0); } _NODISCARD static constexpr int _Days_in_year(const int _Year) { return _Is_leap(_Year) ? 366 : 365; } _NODISCARD static constexpr int _Next_weekday(const int _Wday, const int _Shift) { // 0 <= _Shift <= 6 int _Result = _Wday + _Shift; if (_Result >= 7) { _Result -= 7; } return _Result; } _NODISCARD static constexpr int _Prev_weekday(const int _Wday, const int _Shift) { // 0 <= _Shift <= 6 return (_Wday >= _Shift ? 0 : 7) + (_Wday - _Shift); } _NODISCARD bool _Calculate_ymd_from_week_date(const int _Starting_wday, const int _Week, const int _Year) { // (a) Calculate day-of-year of first _Starting_wday in January. // (b) Shift *_Weekday so that it's relative to _Starting_wday. // (c) Offset to desired week. const int _Jan1_wday = _Jan1_weekday(_Year); const int _Yday = 1 + _Prev_weekday(_Starting_wday, _Jan1_wday) // (a) + _Prev_weekday(*_Weekday, _Starting_wday) // (b) + 7 * (_Week - 1); // (c) return _Update(_Day_of_year, _Yday) && !_Out_of_range(_Day_of_year, 1, _Days_in_year(_Year)) && _Yday_to_month_day(*_Day_of_year, _Year); } _NODISCARD bool _Calculate_ymd() { bool _No_err = true; // Flags to indicate if a field should be checked for consistency with other data. Set to false when the // field is used to calculate the date, as it's necessarily self-consistent in that case (barring a bug). bool _Check_u = true; bool _Check_w = true; bool _Check_iso = true; bool _Check_wday = true; if (_Day_of_year && _Out_of_range(_Day_of_year, 1, 366)) { return false; } bool _Have_year = false; int _Year{0}; if (_Two_dig_year) { _Year = *_Century + *_Two_dig_year; _Have_year = true; if (_Day_of_year) { _No_err = _No_err && _Yday_to_month_day(*_Day_of_year, _Year); } else if (_Week_u || _Week_w) { _Check_wday = false; if (_Week_u) { _Check_u = false; _No_err = _No_err && _Calculate_ymd_from_week_date(0 /*Sunday*/, *_Week_u, _Year); } if (_Week_w) { _Check_w = false; _No_err = _No_err && _Calculate_ymd_from_week_date(1 /*Monday*/, *_Week_w, _Year); } } } if (_Iso_year) { // ISO weeks begin on Monday. W01 always contains January 4. There is no W00, so the beginning of // January can be in W52 or W53 of the previous year. Likewise, the end of December can occur at the // beginning of W01 of the following year, depending on where in the week Jan. 4 falls. _Check_wday = false; _Check_iso = false; _Year = *_Iso_year; _Have_year = true; // Shift weekdays to Monday-based. Jan. 4 is the anchor of week 1, so calculate where the parsed weekday // is relative to that point. const int _Jan4_wday = _Next_weekday(_Jan1_weekday(_Year), 3 - 1); const int _Offset_from_jan4 = _Prev_weekday(*_Weekday, 1) - _Jan4_wday; int _Trial_yday = 4 + 7 * (*_Iso_week - 1) + _Offset_from_jan4; const int _Ref_num_days = _Trial_yday < 1 ? _Days_in_year(_Year - 1) : _Days_in_year(_Year); if (_Trial_yday < 1) { _Trial_yday += _Ref_num_days; --_Year; } else if (_Trial_yday > _Ref_num_days) { _Trial_yday -= _Ref_num_days; ++_Year; } const auto _Year_parts = _Decompose_year(_Year); _No_err = _No_err && _Update(_Day_of_year, _Trial_yday) && _Yday_to_month_day(*_Day_of_year, _Year) && _Update(_Century, _Year_parts.first) && _Update(_Two_dig_year, _Year_parts.second); } // Must have YMD by this point, either parsed directly or calculated above. if (!_Have_year || !_Month || !_Day || !_No_err) { return false; } // consistency checks if (_Check_wday && _Weekday) { const auto _Era_year = _Year - (*_Month <= 2); const int _Era = (_Era_year >= 0 ? _Era_year : _Era_year - 399) / 400; const int _Yoe = _Era_year - _Era * 400; const int _Yday_era = ((979 * (*_Month + (*_Month > 2 ? -3 : 9)) + 19) >> 5) + *_Day - 1; const int _Doe = ((1461 * _Yoe) >> 2) - _Yoe / 100 + _Yday_era; _No_err = _No_err && _Update(_Weekday, (_Doe + _Era_begin_wday) % 7); } if (_Check_u && _Week_u) { _No_err = _No_err && _Update(_Week_u, (*_Day_of_year + 6 - *_Weekday) / 7); } if (_Check_w && _Week_w) { _No_err = _No_err && _Update(_Week_w, (*_Day_of_year + 6 - _Prev_weekday(*_Weekday, 1)) / 7); } if (_Check_iso && _Iso_week) { _No_err = _No_err && _Update(_Iso_week, _Iso8601_week(*_Day_of_year, *_Weekday, _Year)); } return _No_err; } _NODISCARD bool _Calculate_hour24() { if (_Hour_12) { return _Update( _Hour_24, _CHRONO make24(hours{*_Hour_12}, static_cast(_Ampm.value_or(0))).count()); } else { return true; } } _NODISCARD bool _Calculate_year_fields() { bool _No_err = true; // The order of these updates is significant. Updating the ISO date second allows // formats with %g and %y, but not %C, to get the century implicitly from %y. if (_Two_dig_year && !_Century) { _No_err = _No_err && _Update(_Century, _Two_dig_year >= 69 ? 1900 : 2000); } // %C is only combined with %g if %G is missing, to avoid an unnecessary parse failure when the ISO and // Gregorian years are in different centuries. if (_Two_dig_iso_year && _Century && !_Iso_year) { _No_err = _No_err && _Update(_Iso_year, *_Century + *_Two_dig_iso_year); } return _No_err; } _NODISCARD static bool _Out_of_range(const optional& _Field, const int _Min, const int _Max) { return _Field && (_Field < _Min || _Max < _Field); } _NODISCARD bool _Is_complete() const { // Check for data that is incomplete, ambiguous, or obviously out-of-range. The exception is 12-hour time // without am/pm. Most strptime implementations will assume am in this case, so we'll do that too. Don't // check for consistency yet, because the data might not even be representable by the type being parsed, // and calendar computations are relatively expensive. // Most time-of-day fields are deferred until we know if we're parsing a time_point. if (_Out_of_range(_Hour_12, 1, 12) // || _Out_of_range(_Weekday, 0, 6) // || _Out_of_range(_Day, 1, 31) // || _Out_of_range(_Month, 1, 12)) { return false; } if (_Iso_year || _Two_dig_iso_year || _Iso_week) { // Need to have %G or %C+%g. The century can be parsed explicitly, or derived implicitly from %y. const bool _Has_complete_year{_Iso_year || ((_Century || _Two_dig_year) && _Two_dig_iso_year)}; if (!_Has_complete_year || !_Iso_week || !_Weekday || _Out_of_range(_Iso_week, 1, 53)) { return false; } } if (_Week_u || _Week_w) { // Need a weekday and year to be complete. if (!_Weekday || !_Two_dig_year) { return false; } if (_Out_of_range(_Week_u, 0, 53) || _Out_of_range(_Week_w, 0, 53)) { return false; } } return true; } template _NODISCARD static constexpr bool _Can_represent() { using _Rep1 = typename _Duration1::rep; using _Period1 = typename _Duration1::period; using _Period2 = typename _Duration2::period; // Returns whether _Duration1 can represent _Duration2{1}. Assumes 1 <= _Period2 <= // 86,400, i.e., we're interested in time periods between seconds and days. if constexpr (is_integral_v<_Rep1>) { // Must have _Period1 <= _Period2 and numeric_limits<_Rep1>::max() >= _Period2 / _Period1. For example, // std::days can't represent std::seconds, and duration::max() is ~9.2 seconds. constexpr auto _Max_tick = static_cast((numeric_limits>::max) ()); // clang-format off return ratio_less_equal_v<_Period1, _Period2> && ratio_greater_equal_v, ratio_divide, _Period1>>; // clang-format on } else if (is_floating_point_v<_Rep1>) { // With the smallest possible _Period1, ratio<1,INTMAX_MAX>, one day has a tick count of // 86,400*INTMAX_MAX ~= 7.97e23. This is representable by float and double, so they can always represent // at least one day. On the other hand, one second with the largest possible _Period1 needs a tick count // of 1/(INTMAX_MAX) ~= 1.08e-19, which is also representable in both float and double. So, both // floating point types can represent durations between one second and one day, regardless of _Period1. return true; } else { // TRANSITION: user-defined arithmetic-like types return true; } } enum class _Parse_tp_or_duration { _Time_point, _Duration }; template <_Parse_tp_or_duration _Parse_type, class _DurationType> _NODISCARD bool _Apply_duration_fields(_DurationType& _Result) { constexpr bool _Can_rep_sec = _Can_represent<_DurationType, seconds>(); constexpr bool _Can_rep_min = _Can_represent<_DurationType, minutes>(); constexpr bool _Can_rep_hr = _Can_represent<_DurationType, hours>(); constexpr bool _Can_rep_day = _Can_represent<_DurationType, days>(); constexpr bool _For_time_point = _Parse_type == _Parse_tp_or_duration::_Time_point; const auto _Required{(_For_time_point ? _F_day | _F_mon | _F_year : 0)}; const auto _Optional{(_For_time_point ? _F_wkday : 0) | (_Can_rep_sec ? _F_sec : 0) | (_Can_rep_min ? _F_min : 0) | (_Can_rep_hr ? _F_hr : 0) | (_Can_rep_day ? _F_doy : 0)}; const auto _Used{_Used_fields()}; const auto _Time_out_of_range{ _For_time_point && (_Out_of_range(_Second, 0, 60) || _Out_of_range(_Minute, 0, 59) || _Out_of_range(_Hour_24, 0, 23))}; if (_Time_out_of_range || !_Test_bits(_Used, _Required, _Optional)) { return false; } _Result = _DurationType::zero(); if constexpr (_Can_rep_sec) { if (_Used & _F_sec) { if (_Subsecond) { using _CastedType = duration; const _SubsecondType _Sub{*_Subsecond}; if (treat_as_floating_point_v<_DurationType> // || _CHRONO duration_cast<_CastedType>(_Sub) == _Sub) { _Result += _CHRONO duration_cast<_DurationType>(_Sub); } else { return false; } } if (_Second) { _Result += _CHRONO duration_cast<_DurationType>(seconds{*_Second}); } } } if constexpr (_Can_rep_min) { if (_Used & _F_min) { _Result += _CHRONO duration_cast<_DurationType>(minutes{*_Minute}); } if (_Utc_offset) { _Result -= _CHRONO duration_cast<_DurationType>(minutes{*_Utc_offset}); } } if constexpr (_Can_rep_hr) { if (_Used & _F_hr) { _Result += _CHRONO duration_cast<_DurationType>(hours{*_Hour_24}); } } if constexpr (_Can_rep_day) { if (_For_time_point) { const year_month_day _Ymd{year{*_Century + *_Two_dig_year}, month{static_cast(*_Month)}, day{static_cast(*_Day)}}; _Result += _CHRONO duration_cast<_DurationType>(static_cast(_Ymd).time_since_epoch()); } else if (_Used & _F_doy) { _Result += _CHRONO duration_cast<_DurationType>(days{*_Day_of_year}); } } return true; } template _NODISCARD bool _Make_duration(duration<_Rep, _Period>& _Duration_result) { const bool _Consistent = _Calculate_hour24(); if (_Consistent) { _Duration_result = duration<_Rep, _Period>::zero(); // TRANSITION: LWG-3536 & GH-1740 return _Apply_duration_fields<_Parse_tp_or_duration::_Duration>(_Duration_result); } return false; } enum class _LeapSecondRep : unsigned int { _None, // tai_clock, gps_clock; oblivious to leap seconds _Negative, // system_clock, observes negative, but not positive, leap seconds _All, // utc_clock _File_time // _Negative before 1 January 2017, _All afterwards. }; template _NODISCARD bool _Make_time_point(_DurationType& _Dur, _LeapSecondRep _Leap) { const bool _Consistent{_Calculate_hour24() && _Calculate_year_fields() && _Calculate_ymd()}; if (!_Consistent || !_Apply_duration_fields<_Parse_tp_or_duration::_Time_point>(_Dur)) { return false; } const _LeapSecondRep _Original_leap{_Leap}; if (_Leap == _LeapSecondRep::_File_time) { const int _Year{*_Century + *_Two_dig_year}; _Leap = _Year <= 2016 ? _LeapSecondRep::_Negative : _LeapSecondRep::_All; } if (_Second > (_Leap == _LeapSecondRep::_All ? 60 : 59)) { return false; } // A distinction has to be made here between clocks that tick monotonically, even around a positive leap // second (everything except system_clock) and ones that have a special representation for leap seconds // (utc_clock and, for negative leap seconds, system_clock). gps_clock and tai_clock, in particular, always // monotonically count 86,400 seconds/day. The correct tick count, therefore, can be determined without // knowing whether any leap seconds have occurred, and there aren't any invalid times due to negative leap // second deletions. // // system_clock also has 86,400 seconds/day, but observes negative leap seconds by skipping them in its tick // count. So leap second data is needed to check for a valid time, but not to calculate the tick count. if (_Leap != _LeapSecondRep::_None) { if (_Hour_24 == 23 && _Minute == 59 && _Second >= 59) { // It's possible that the parsed time doesn't exist because (a) _Seconds == 60 and there *isn't* a // leap second insertion or (b) _Seconds == 59 and there *is* a leap second subtraction. // Check for quick exit. const auto& _Tzdb{_CHRONO get_tzdb()}; if (_Leap == _LeapSecondRep::_Negative && _Tzdb._All_ls_positive) { return true; } const bool _Possible_insertion{_Second == 60}; const sys_seconds _Target_sys_time{ _CHRONO floor(_Dur) + (_Possible_insertion ? seconds{0} : seconds{1})}; const auto& _Ls_vector{_Tzdb.leap_seconds}; const auto _It{_STD lower_bound(_Ls_vector.begin(), _Ls_vector.end(), _Target_sys_time)}; const bool _Match_leap{_It != _Ls_vector.end() && *_It == _Target_sys_time}; // Condition for a good parse: (_Seconds == 59 && !_Match_leap) || (_Match_leap && // _It->_Is_positive()). Below is the inverse of this. if (!(_Match_leap ? _It->_Positive() : !_Possible_insertion)) { return false; } } if (_Leap == _LeapSecondRep::_All) { constexpr bool _Can_rep_sec = _Can_represent<_DurationType, seconds>(); if constexpr (_Can_rep_sec) { _Dur = utc_clock::from_sys(sys_time<_DurationType>{_Dur}).time_since_epoch(); // If we parsed a positive leap second, then _Dur, interpreted as a system time, refers to the // second *after* insertion. Need to back up one second in this case. if (_Second == 60) { _Dur -= _CHRONO duration_cast<_DurationType>(seconds{1}); } if (_Original_leap == _LeapSecondRep::_File_time) { _Dur -= _CHRONO duration_cast<_DurationType>( filesystem::_File_time_clock::_Skipped_filetime_leap_seconds); } } else { // Error if _Dur can't represent the above adjustment. return false; } } } return true; } _NODISCARD bool _Make_day(day& _Day_result) { if (_Used_fields() == _F_day) { _Day_result = day{static_cast(*_Day)}; return true; } else { return false; } } _NODISCARD bool _Make_weekday(weekday& _Weekday_result) { if (_Used_fields() == _F_wkday) { _Weekday_result = weekday{static_cast(*_Weekday)}; return true; } else { return false; } } _NODISCARD bool _Make_month(month& _Month_result) { if (_Used_fields() == _F_mon) { _Month_result = month{static_cast(*_Month)}; return true; } else { return false; } } _NODISCARD bool _Make_month_day(month_day& _Month_day_result) { if (_Day_of_year && !_Yday_to_month_day(*_Day_of_year, 0)) { return false; } constexpr auto _Required = _F_mon | _F_day; constexpr auto _Optional = _F_doy; if (_Test_bits(_Used_fields(), _Required, _Optional)) { _Month_day_result = month_day{month{static_cast(*_Month)}, day{static_cast(*_Day)}}; return true; } else { return false; } } _NODISCARD bool _Make_year(year& _Year_result) { if (_Calculate_year_fields() && _Used_fields() == _F_year) { _Year_result = year{*_Century + *_Two_dig_year}; return true; } else { return false; } } _NODISCARD bool _Make_year_month(year_month& _Year_month_result) { if (_Calculate_year_fields() && _Used_fields() == (_F_mon | _F_year)) { _Year_month_result = year_month{year{*_Century + *_Two_dig_year}, month{static_cast(*_Month)}}; return true; } else { return false; } } _NODISCARD bool _Make_year_month_day( year_month_day& _Year_month_day_result, const bool _For_time_point = false) { const bool _Consistent = _Calculate_year_fields() && _Calculate_ymd(); constexpr auto _Required = _F_day | _F_mon | _F_year; auto _Optional = _F_wkday | _F_doy; if (_For_time_point) { // These fields aren't used here, but they might be used later if converting to a time_point. _Optional |= _F_sec | _F_min | _F_hr; } if (_Consistent && _Test_bits(_Used_fields(), _Required, _Optional)) { _Year_month_day_result = year_month_day{year{*_Century + *_Two_dig_year}, month{static_cast(*_Month)}, day{static_cast(*_Day)}}; return true; } else { return false; } } template _NODISCARD _InIt _Parse_time_field(_InIt _First, ios_base& _Iosbase, ios_base::iostate& _State, const char _Flag, const char _Modifier, const unsigned int _Width, const unsigned int _Subsecond_precision) { using _CharT = typename _InIt::value_type; const auto& _Ctype_fac = _STD use_facet>(_Iosbase.getloc()); const auto& _Time_fac = _STD use_facet>(_Iosbase.getloc()); constexpr _InIt _Last{}; int _Val{0}; switch (_Flag) { case 'a': case 'A': { tm _Tp; _Tp.tm_wday = _Invalid_time_field; _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, 'a'); if (!_Update(_Weekday, _Tp.tm_wday)) { _State |= ios_base::failbit; } break; } case 'b': case 'B': case 'h': { tm _Tp; _Tp.tm_mon = _Invalid_time_field; _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, 'b'); if (_Tp.tm_mon == _Invalid_time_field || !_Update(_Month, ++_Tp.tm_mon)) { _State |= ios_base::failbit; } break; } case 'C': if (_Modifier != 'E') { _State |= _Get_int(_First, _Width == 0 ? 2u : _Width, _Val, _Ctype_fac); _Val *= 100; } else { tm _Tp; _Tp.tm_year = _Invalid_time_field; _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, 'C', 'E'); _Val = _Tp.tm_year; if (_Tp.tm_year != _Invalid_time_field) { _Val += 1900; } } if (!_Update(_Century, _Val)) { _State |= ios_base::failbit; } break; case 'd': case 'e': if (_Modifier != 'O') { _State |= _Get_int(_First, _Width == 0 ? 2u : _Width, _Val, _Ctype_fac); } else { tm _Tp; _Tp.tm_mday = _Invalid_time_field; _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, 'd', 'O'); _Val = _Tp.tm_mday; } if (!_Update(_Day, _Val)) { _State |= ios_base::failbit; } break; case 'D': _First = _Parse_time_field_restricted(_First, _Iosbase, _State, "%m/%d/%y"); break; case 'F': { // If modified with a width N, the width is applied to only %Y. _State |= _Get_int(_First, _Width == 0 ? 4u : _Width, _Val, _Ctype_fac); const auto _Year_parts = _Decompose_year(_Val); if (_Update(_Century, _Year_parts.first) && _Update(_Two_dig_year, _Year_parts.second)) { _First = _Parse_time_field_restricted(_First, _Iosbase, _State, "-%m-%d"); } else { _State |= ios_base::failbit; } break; } case 'g': _State |= _Get_int(_First, _Width == 0 ? 2u : _Width, _Val, _Ctype_fac); if (!_Update(_Two_dig_iso_year, _Val)) { _State |= ios_base::failbit; } break; case 'G': { _State |= _Get_int(_First, _Width == 0 ? 4u : _Width, _Val, _Ctype_fac); const auto _Year_parts = _Decompose_year(_Val); if (!_Update(_Iso_year, _Val) || !_Update(_Two_dig_iso_year, _Year_parts.second)) { _State |= ios_base::failbit; } break; } case 'H': if (_Modifier != 'O') { _State |= _Get_int(_First, _Width == 0 ? 2u : _Width, _Val, _Ctype_fac); } else { tm _Tp; _Tp.tm_hour = _Invalid_time_field; _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, 'H', 'O'); _Val = _Tp.tm_hour; } if (!_Update(_Hour_24, _Val) || (_Val < 24 && (!_Update(_Ampm, _Val >= 12 ? 1 : 0) || !_Update(_Hour_12, _CHRONO make12(hours{_Val}).count())))) { _State |= ios_base::failbit; } break; case 'I': if (_Modifier != 'O') { _State |= _Get_int(_First, _Width == 0 ? 2u : _Width, _Val, _Ctype_fac); } else { tm _Tp; _Tp.tm_hour = _Invalid_time_field; _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, 'I', 'O'); _Val = (_Tp.tm_hour == 0) ? 12 : _Tp.tm_hour; } if (!_Update(_Hour_12, _Val)) { _State |= ios_base::failbit; } break; case 'j': _State |= _Get_int(_First, _Width == 0 ? 3u : _Width, _Val, _Ctype_fac); if (!_Update(_Day_of_year, _Val)) { _State |= ios_base::failbit; } break; case 'M': if (_Modifier != 'O') { _State |= _Get_int(_First, _Width == 0 ? 2u : _Width, _Val, _Ctype_fac); } else { tm _Tp; _Tp.tm_min = _Invalid_time_field; _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, 'M', 'O'); _Val = _Tp.tm_min; } if (!_Update(_Minute, _Val)) { _State |= ios_base::failbit; } break; case 'm': if (_Modifier != 'O') { _State |= _Get_int(_First, _Width == 0 ? 2u : _Width, _Val, _Ctype_fac); } else { tm _Tp; _Initialize_time_point(_Tp); _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, 'm', 'O'); _Val = _Tp.tm_mon; if (_Tp.tm_mon != _Invalid_time_field) { ++_Val; } } if (!_Update(_Month, _Val)) { _State |= ios_base::failbit; } break; case 'p': { tm _Tp; _Tp.tm_hour = 0; _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, 'p'); if (!_Update(_Ampm, _Tp.tm_hour == 0 ? 0 : 1)) { _State |= ios_base::failbit; } break; } case 'c': case 'r': case 'x': case 'X': { tm _Tp; _Initialize_time_point(_Tp); const bool _Full_year = (_Flag == 'c'); // 'x' reads two-digit year, 'r' and 'X' read times _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, _Flag, _Modifier); if (!_Update_if_valid(_Tp, _Full_year)) { _State |= ios_base::failbit; } break; } case 'R': _First = _Parse_time_field_restricted(_First, _Iosbase, _State, "%H:%M"); break; case 'T': _First = _Parse_time_field_restricted(_First, _Iosbase, _State, "%H:%M:%S", _Subsecond_precision); break; case 'S': if (_Subsecond_precision == 0) { _State |= _Get_int(_First, _Width == 0 ? 2u : _Width, _Val, _Ctype_fac); if (!_Update(_Second, _Val)) { _State |= ios_base::failbit; } } else { const auto& _Numpunct_fac = _STD use_facet>(_Iosbase.getloc()); _State |= _Get_fixed(_First, _Width == 0 ? 3 + _Subsecond_precision : _Width, _Ctype_fac, _Numpunct_fac); } break; case 'u': case 'w': if (_Flag == 'w' && _Modifier == 'O') { tm _Tp; _Tp.tm_wday = _Invalid_time_field; _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, 'w', 'O'); _Val = _Tp.tm_wday; } else { _State |= _Get_int(_First, _Width == 0 ? 1u : _Width, _Val, _Ctype_fac); if (_Flag == 'u') { // ISO weekday: [1,7], 7 == Sunday if (_Val == 7) { _Val = 0; } else if (_Val == 0) { _Val = 7; // out of range } } } if (!_Update(_Weekday, _Val)) { _State |= ios_base::failbit; } break; case 'U': case 'V': case 'W': { _State |= _Get_int(_First, _Width == 0 ? 2u : _Width, _Val, _Ctype_fac); auto& _Field{(_Flag == 'U') ? _Week_u : (_Flag == 'W' ? _Week_w : _Iso_week)}; if (!_Update(_Field, _Val)) { _State |= ios_base::failbit; } break; } case 'y': if (_Modifier == '\0') { _State |= _Get_int(_First, _Width == 0 ? 2u : _Width, _Val, _Ctype_fac); } else { tm _Tp; _Tp.tm_year = _Invalid_time_field; _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, 'y', _Modifier); if (_Modifier == 'E') { _Val = _Tp.tm_year + 1900; // offset from %EC base year } else { const auto _Year_parts = _Decompose_year(_Tp.tm_year); _Val = _Year_parts.second; } } if (!_Update(_Two_dig_year, _Val)) { _State |= ios_base::failbit; } break; case 'Y': { if (_Modifier == 'E') { tm _Tp; _Tp.tm_year = _Invalid_time_field; _First = _Time_fac.get(_First, _Last, _Iosbase, _State, &_Tp, 'Y', 'E'); _Val = _Tp.tm_year + 1900; } else { _State |= _Get_int(_First, _Width == 0 ? 4u : _Width, _Val, _Ctype_fac); } const auto _Year_parts = _Decompose_year(_Val); if (!_Update(_Century, _Year_parts.first) || !_Update(_Two_dig_year, _Year_parts.second)) { _State |= ios_base::failbit; } break; } case 'z': _State |= _Get_tz_offset(_First, _Ctype_fac, _Modifier == 'E' || _Modifier == 'O', _Val); if (!_Update(_Utc_offset, _Val)) { _State |= ios_base::failbit; } break; case 'Z': { string _Name; _State |= _Get_tz_name(_First, _Ctype_fac, _Name); if (!_Update(_Tz_name, _Name)) { _State |= ios_base::failbit; } break; } default: // Invalid flag _State |= ios_base::failbit; break; } return _First; } template _NODISCARD _InIt _Parse_time_field_restricted(_InIt _First, ios_base& _Iosbase, ios_base::iostate& _State, const char* _Fmt, const unsigned int _Subsecond_precision = 0) { using _Ctype = ctype; // Parses a restricted format string. It generally doesn't handle anything parsed outside of // _Parse_time_field: // (a) any whitespace (' ', %n, %t) // (b) %% literal (other literals are parsed, however) // (c) E or O modifiers // (d) width parameter // It also assumes a valid format string, specifically that '%' is always followed by a flag. const _Ctype& _Ctype_fac{_STD use_facet<_Ctype>(_Iosbase.getloc())}; constexpr _InIt _Last{}; while (*_Fmt != '\0' && _First != _Last && _State == ios_base::goodbit) { if (*_Fmt == '%') { _First = _Parse_time_field(_First, _Iosbase, _State, *++_Fmt, '\0', 0, _Subsecond_precision); } else if (_Ctype_fac.narrow(*_First++) != *_Fmt) { _State |= ios_base::failbit; } ++_Fmt; } return _First; } template _NODISCARD ios_base::iostate _Get_fixed(_InIt& _First, unsigned int _Width, const ctype& _Ctype_fac, const numpunct& _Numpunct_fac) { constexpr _InIt _Last{}; while (_First != _Last && _Ctype_fac.is(ctype_base::space, *_First) && _Width > 0) { ++_First; --_Width; } int _Second_ = 0; int64_t _Subsecond_ = 0; int64_t _Multiplier = _SubsecondType::period::den; bool _Found_point = false; bool _Found_digit = false; while (_First != _Last && _Width > 0 && _Multiplier >= 10) { const auto _Ch = *_First; if (_Ch == _Numpunct_fac.decimal_point() && !_Found_point) { _Found_point = true; } else if (_Ctype_fac.is(ctype_base::digit, _Ch)) { _Found_digit = true; const auto _Digit = _Ctype_fac.narrow(_Ch) - '0'; if (_Found_point) { _Multiplier /= 10; _Subsecond_ += _Digit * _Multiplier; } else { if (_Second_ > ((numeric_limits::max) () - _Digit) / 10) { return ios_base::failbit; } _Second_ = _Second_ * 10 + _Digit; } } else { break; } ++_First; --_Width; } ios_base::iostate _State = ios_base::goodbit; if (_First == _Last) { _State |= ios_base::eofbit; } if (!(_Found_digit && _Update(_Second, _Second_) && _Update(_Subsecond, _Subsecond_))) { _State |= ios_base::failbit; } return _State; } template _NODISCARD ios_base::iostate _Get_int( _InIt& _First, unsigned int _Width, int& _Val, const ctype& _Ctype_fac) { constexpr _InIt _Last{}; while (_First != _Last && _Ctype_fac.is(ctype_base::space, *_First) && _Width > 0) { ++_First; --_Width; } char _Ac[_MAX_INT_DIG]; char* _Ptr = _Ac; if (_First != _Last && _Width > 0) { const char _Ch = _Ctype_fac.narrow(*_First); if (_Ch == '+' || _Ch == '-') { // copy sign *_Ptr++ = _Ch; ++_First; --_Width; } } bool _Has_leading_zero = false; while (_First != _Last && _Width > 0 && _Ctype_fac.narrow(*_First) == '0') { // strip leading zeros ++_First; --_Width; _Has_leading_zero = true; } if (_Has_leading_zero) { *_Ptr++ = '0'; } char _Ch; while (_First != _Last && _Width > 0 && '0' <= (_Ch = _Ctype_fac.narrow(*_First)) && _Ch <= '9') { // copy digits *_Ptr = _Ch; if (_Ptr < _STD cend(_Ac)) { ++_Ptr; // drop trailing digits if already too large } ++_First; --_Width; } *_Ptr = '\0'; int _Errno = 0; char* _Ep; const long _Ans = _CSTD _Stolx(_Ac, &_Ep, 10, &_Errno); ios_base::iostate _State = ios_base::goodbit; if (_First == _Last) { _State |= ios_base::eofbit; } if (_Ep == _Ac || _Errno != 0) { _State |= ios_base::failbit; // bad conversion } else { _Val = _Ans; // store valid result } return _State; } template _NODISCARD ios_base::iostate _Get_tz_offset( _InIt& _First, const ctype& _Ctype_fac, const bool _Is_modified, int& _Offset) { constexpr _InIt _Last{}; if (_First == _Last) { return ios_base::eofbit; } bool _Negative = false; switch (_Ctype_fac.narrow(*_First)) { case '-': _Negative = true; [[fallthrough]]; case '+': ++_First; break; } // For a regular offset hh[mm], simply read four digits, with the option of an EOF or non-digit after // reading two. The modified form h[h][:mm] is similar, except for the following points: // (a) an EOF or non-digit is allowable after reading *one* digit, not two. // (b) after reading one digit, another optional digit keeps us in the same state, except for decrementing // the number of optional digits allowed. In this state, reading a ':' allows parsing to continue. int _Tz_hours = 0; int _Tz_minutes = 0; int _Optional_digits = 1; for (int _Count = 0; _Count < 4; ++_Count) { const bool _Allow_match_fail{_Count == (_Is_modified ? 1 : 2)}; if (_First == _Last) { if (_Allow_match_fail) { break; } else { return ios_base::eofbit | ios_base::failbit; } } const char _Ch = _Ctype_fac.narrow(*_First++); const bool _Is_digit = ('0' <= _Ch && _Ch <= '9'); if (_Is_modified && _Count == 1) { if (_Ch == ':') { continue; } else if (_Is_digit && _Optional_digits > 0) { _Tz_hours = 10 * _Tz_hours + (_Ch - '0'); --_Optional_digits; --_Count; } else { if (_Allow_match_fail) { break; } else { return ios_base::failbit; } } } else if (_Is_digit) { auto& _Part = _Count < 2 ? _Tz_hours : _Tz_minutes; _Part = 10 * _Part + (_Ch - '0'); } else { if (_Allow_match_fail) { break; } else { return ios_base::failbit; } } } _Offset = 60 * _Tz_hours + _Tz_minutes; if (_Negative) { _Offset = -_Offset; } return ios_base::goodbit; } template _NODISCARD ios_base::iostate _Get_tz_name( _InIt& _First, const ctype& _Ctype_fac, string& _Tz_name) { constexpr _InIt _Last{}; _Tz_name.clear(); while (_First != _Last) { const char _Ch{_Ctype_fac.narrow(*_First)}; if (_STD isalnum(static_cast(_Ch)) || _Ch == '_' || _Ch == '/' || _Ch == '-' || _Ch == '+') { _Tz_name.push_back(_Ch); ++_First; } else { break; } } return _First == _Last ? ios_base::eofbit : ios_base::goodbit; } template > _Time_parse_fields(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _FmtFirst, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr, unsigned int _Subsecond_precision = 0) { using _Myis = basic_istream<_CharT, _Traits>; const auto& _Ctype_fac = _STD use_facet>(_Istr.getloc()); ios_base::iostate _State = ios_base::goodbit; const _CharT* const _FmtLast = _FmtFirst + _Traits::length(_FmtFirst); const typename _Myis::sentry _Ok{_Istr, true}; istreambuf_iterator _First{_Istr}; constexpr decltype(_First) _Last{}; if (_Ok) { _TRY_IO_BEGIN for (; _FmtFirst != _FmtLast && _State == ios_base::goodbit; ++_FmtFirst) { if (_First == _Last) { // EOF is not an error if the remaining flags can match zero characters. for (; _FmtFirst != _FmtLast; ++_FmtFirst) { char _Flag{}; if (_Ctype_fac.is(ctype_base::space, *_FmtFirst)) { _Flag = ' '; } else { if (_Ctype_fac.narrow(*_FmtFirst) == '%' && ++_FmtFirst != _FmtLast) { _Flag = _Ctype_fac.narrow(*_FmtFirst); } } if (_Flag != ' ' && _Flag != 't') { _State |= ios_base::failbit | ios_base::eofbit; break; } } break; } else if (_Ctype_fac.narrow(*_FmtFirst) != '%') { // match literal element if (_Ctype_fac.is(ctype_base::space, *_FmtFirst)) { while (_First != _Last && _Ctype_fac.is(ctype_base::space, *_First)) { ++_First; } } else if (*_First == *_FmtFirst) { ++_First; } else { _State |= ios_base::failbit; // bad literal match } } else if (++_FmtFirst == _FmtLast) { // not enough for a valid flag _State |= ios_base::failbit; } else { // get flag after % char _Flag = _Ctype_fac.narrow(*_FmtFirst); char _Modifier = '\0'; unsigned int _Width = 0; if (_Flag == 'E' || _Flag == 'O') { if (++_FmtFirst == _FmtLast) { _State |= ios_base::failbit; break; } _Modifier = _STD exchange(_Flag, _Ctype_fac.narrow(*_FmtFirst)); } else if ('0' <= _Flag && _Flag <= '9') { _Width = static_cast(_Flag - '0'); while (++_FmtFirst != _FmtLast && _Ctype_fac.is(ctype_base::digit, *_FmtFirst)) { const auto _Digit = static_cast(_Ctype_fac.narrow(*_FmtFirst) - '0'); if (_Width > ((numeric_limits::max) () - _Digit) / 10) { _State |= ios_base::failbit; break; } _Width = 10 * _Width + _Digit; } if (_FmtFirst == _FmtLast) { _State |= ios_base::failbit; break; } _Flag = _Ctype_fac.narrow(*_FmtFirst); } switch (_Flag) { case 'n': // exactly one space if (!_Ctype_fac.is(ctype_base::space, *_First++)) { _State |= ios_base::failbit; } break; case 't': // zero or one space if (_Ctype_fac.is(ctype_base::space, *_First)) { ++_First; } break; case '%': if (_Ctype_fac.narrow(*_First++) != '%') { _State |= ios_base::failbit; } break; default: _First = _Parse_time_field(_First, _Istr, _State, _Flag, _Modifier, _Width, _Subsecond_precision); // convert a single field break; } } } _CATCH_IO_(_Myis, _Istr) } if (!_Is_complete()) { _State |= ios_base::failbit; } if (!(_State & ios_base::failbit)) { if (_Offset != nullptr && _Utc_offset) { *_Offset = minutes{*_Utc_offset}; } if (_Abbrev != nullptr && _Tz_name) { if constexpr (is_same_v) { *_Abbrev = _STD move(*_Tz_name); } else { _Abbrev->clear(); for (const char& _Ch : *_Tz_name) { _Abbrev->push_back(_Ctype_fac.widen(_Ch)); } } } } _Istr.setstate(_State); } }; template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, duration<_Rep, _Period>& _Duration, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr) { _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset, hh_mm_ss>::fractional_width}; if (_Istr && !_Time._Make_duration(_Duration)) { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, weekday& _Wd, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr) { _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset}; if (_Istr && !_Time._Make_weekday(_Wd)) { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, day& _Day, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr) { _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset}; if (_Istr && !_Time._Make_day(_Day)) { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, month& _Month, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr) { _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset}; if (_Istr && !_Time._Make_month(_Month)) { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, month_day& _Md, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr) { _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset}; if (_Istr && !_Time._Make_month_day(_Md)) { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, year& _Year, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr) { _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset}; if (_Istr && !_Time._Make_year(_Year)) { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, year_month& _Ym, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr) { _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset}; if (_Istr && !_Time._Make_year_month(_Ym)) { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, year_month_day& _Ymd, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr) { _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset}; if (_Istr && !_Time._Make_year_month_day(_Ymd)) { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, utc_time<_Duration>& _Tp, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr) { constexpr auto _Subsecond_precision{hh_mm_ss<_Duration>::fractional_width}; _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset, _Subsecond_precision}; _Duration _Dur; if (_Istr && _Time._Make_time_point(_Dur, _Time_parse_fields::_LeapSecondRep::_All)) { _Tp = utc_time<_Duration>{_Dur}; } else { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, sys_time<_Duration>& _Tp, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr) { constexpr auto _Subsecond_precision{hh_mm_ss<_Duration>::fractional_width}; _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset, _Subsecond_precision}; _Duration _Dur; if (_Istr && _Time._Make_time_point(_Dur, _Time_parse_fields::_LeapSecondRep::_Negative)) { _Tp = sys_time<_Duration>{_Dur}; } else { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, tai_time<_Duration>& _Tp, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr) { constexpr auto _Subsecond_precision{hh_mm_ss<_Duration>::fractional_width}; _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset, _Subsecond_precision}; _Duration _Dur; if (_Istr && _Time._Make_time_point(_Dur, _Time_parse_fields::_LeapSecondRep::_None)) { _Tp = tai_time<_Duration>{_Dur + _CHRONO duration_cast<_Duration>(days{4383})}; } else { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, gps_time<_Duration>& _Tp, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, chrono::minutes* _Offset = nullptr) { constexpr auto _Subsecond_precision{hh_mm_ss<_Duration>::fractional_width}; _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset, _Subsecond_precision}; _Duration _Dur; if (_Istr && _Time._Make_time_point(_Dur, _Time_parse_fields::_LeapSecondRep::_None)) { _Tp = gps_time<_Duration>{_Dur - _CHRONO duration_cast<_Duration>(days{3657})}; } else { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, file_time<_Duration>& _Tp, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, chrono::minutes* _Offset = nullptr) { constexpr auto _Subsecond_precision{hh_mm_ss<_Duration>::fractional_width}; _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset, _Subsecond_precision}; _Duration _Dur; if (_Istr && _Time._Make_time_point(_Dur, _Time_parse_fields::_LeapSecondRep::_File_time)) { constexpr auto _File_clock_adj{_CHRONO duration_cast<_Duration>( filesystem::_File_time_clock::duration{filesystem::__std_fs_file_time_epoch_adjustment})}; _Tp = file_time<_Duration>{_Dur} + _File_clock_adj; } else { _Istr.setstate(ios_base::failbit); } return _Istr; } template > basic_istream<_CharT, _Traits>& from_stream(basic_istream<_CharT, _Traits>& _Istr, const _CharT* _Fmt, local_time<_Duration>& _Tp, basic_string<_CharT, _Traits, _Alloc>* _Abbrev = nullptr, minutes* _Offset = nullptr) { constexpr auto _Subsecond_precision{hh_mm_ss<_Duration>::fractional_width}; _Time_parse_fields _Time{_Istr, _Fmt, _Abbrev, _Offset, _Subsecond_precision}; // *_Offset is not subtracted from local_time, see N4885 [time.clock.local]/4. _Time._Utc_offset.reset(); _Duration _Dur; if (_Istr && _Time._Make_time_point(_Dur, _Time_parse_fields::_LeapSecondRep::_None)) { _Tp = local_time<_Duration>{_Dur}; } else { _Istr.setstate(ios_base::failbit); } return _Istr; } template struct _Time_parse_iomanip { _Time_parse_iomanip(const basic_string<_CharT, _Traits, _Alloc>& _Fmt_, _Parsable& _Tp_, basic_string<_CharT, _Traits, _Alloc>* _Abbrev_ = nullptr, minutes* _Offset_ = nullptr) : _Fmt{_Fmt_}, _Tp{_Tp_}, _Abbrev{_Abbrev_}, _Offset{_Offset_} {} const basic_string<_CharT, _Traits, _Alloc>& _Fmt; _Parsable& _Tp; basic_string<_CharT, _Traits, _Alloc>* _Abbrev; minutes* _Offset; }; template &>(), _STD declval(), _STD declval<_Parsable&>()))>> _NODISCARD auto parse(const basic_string<_CharT, _Traits, _Alloc>& _Fmt, _Parsable& _Tp) { return _Time_parse_iomanip{_Fmt, _Tp}; } template &>(), _STD declval(), _STD declval<_Parsable&>(), _STD declval*>()))>> _NODISCARD auto parse(const basic_string<_CharT, _Traits, _Alloc>& _Fmt, _Parsable& _Tp, basic_string<_CharT, _Traits, _Alloc>& _Abbrev) { return _Time_parse_iomanip{_Fmt, _Tp, _STD addressof(_Abbrev)}; } template &>(), _STD declval(), _STD declval<_Parsable&>(), _STD declval*>(), _STD declval()))>> _NODISCARD auto parse(const basic_string<_CharT, _Traits, _Alloc>& _Fmt, _Parsable& _Tp, minutes& _Offset) { return _Time_parse_iomanip{_Fmt, _Tp, static_cast*>(nullptr), &_Offset}; } template &>(), _STD declval(), _STD declval<_Parsable&>(), _STD declval*>(), _STD declval()))>> _NODISCARD auto parse(const basic_string<_CharT, _Traits, _Alloc>& _Fmt, _Parsable& _Tp, basic_string<_CharT, _Traits, _Alloc>& _Abbrev, minutes& _Offset) { return _Time_parse_iomanip{_Fmt, _Tp, _STD addressof(_Abbrev), &_Offset}; } template basic_istream<_CharT, _Traits>& operator>>( basic_istream<_CharT, _Traits>& _Is, const _Time_parse_iomanip<_CharT, _Traits, _Alloc, _Parsable>& _Tpi) { return _CHRONO from_stream(_Is, _Tpi._Fmt.c_str(), _Tpi._Tp, _Tpi._Abbrev, _Tpi._Offset); } #endif // _HAS_CXX20 } // namespace chrono #ifdef __cpp_lib_format // [time.format] template _NODISCARD constexpr const _CharT* _Choose_literal(const char* const _Str, const wchar_t* const _WStr) noexcept { if constexpr (is_same_v<_CharT, char>) { return _Str; } else { return _WStr; } } #define _STATICALLY_WIDEN(_CharT, _Literal) (_Choose_literal<_CharT>(_Literal, L##_Literal)) // clang-format off template concept _Chrono_parse_spec_callbacks = _Parse_align_callbacks<_Ty, _CharT> && _Parse_width_callbacks<_Ty, _CharT> && _Parse_precision_callbacks<_Ty, _CharT> && _Width_adapter_callbacks<_Ty, _CharT> && _Precision_adapter_callbacks<_Ty, _CharT> && requires(_Ty _At, basic_string_view<_CharT> _Sv, _Fmt_align _Aln) { { _At._On_conversion_spec(char{}, _CharT{}) } -> same_as; { _At._On_lit_char(_CharT{}) } -> same_as; }; // clang-format on // clang-format off template concept _Has_ok = requires(_Ty _At) { { _At.ok() } -> same_as; }; // clang-format on // A chrono spec is either a type (with an optional modifier), OR a literal character, never both. template struct _Chrono_spec { _CharT _Lit_char = _CharT{'\0'}; // any character other than '{', '}', or '%' char _Modifier = '\0'; // either 'E' or 'O' char _Type = '\0'; }; template struct _Chrono_format_specs { int _Width = 0; int _Precision = -1; int _Dynamic_width_index = -1; int _Dynamic_precision_index = -1; _Fmt_align _Alignment = _Fmt_align::_None; uint8_t _Fill_length = 1; // At most one codepoint (so one char32_t or four utf-8 char8_t) _CharT _Fill[4 / sizeof(_CharT)] = {_CharT{' '}}; // recursive definition in grammar, so could have any number of these vector<_Chrono_spec<_CharT>> _Chrono_specs_list; }; // Model of _Chrono_parse_spec_callbacks that fills a _Chrono_format_specs with the parsed data template class _Chrono_specs_setter { public: constexpr explicit _Chrono_specs_setter(_Chrono_format_specs<_CharT>& _Specs_, _ParseContext& _Parse_ctx_) : _Specs(_Specs_), _Parse_ctx(_Parse_ctx_) {} // same as _Specs_setter constexpr void _On_align(_Fmt_align _Aln) { _Specs._Alignment = _Aln; } // same as _Specs_setter constexpr void _On_fill(basic_string_view<_CharT> _Sv) { if (_Sv.size() > _STD size(_Specs._Fill)) { _THROW(format_error("Invalid fill (too long).")); } const auto _Pos = _STD _Copy_unchecked(_Sv._Unchecked_begin(), _Sv._Unchecked_end(), _Specs._Fill); _STD fill(_Pos, _STD end(_Specs._Fill), _CharT{}); _Specs._Fill_length = static_cast(_Sv.size()); } constexpr void _On_width(int _Width) { _Specs._Width = _Width; } constexpr void _On_precision(int _Prec) { _Specs._Precision = _Prec; } constexpr void _On_dynamic_width(const size_t _Arg_id) { _Parse_ctx.check_arg_id(_Arg_id); _Specs._Dynamic_width_index = _Verify_dynamic_arg_index_in_range(_Arg_id); } constexpr void _On_dynamic_width(_Auto_id_tag) { _Specs._Dynamic_width_index = _Verify_dynamic_arg_index_in_range(_Parse_ctx.next_arg_id()); } constexpr void _On_dynamic_precision(const size_t _Arg_id) { _Parse_ctx.check_arg_id(_Arg_id); _Specs._Dynamic_precision_index = _Verify_dynamic_arg_index_in_range(_Arg_id); } constexpr void _On_dynamic_precision(_Auto_id_tag) { _Specs._Dynamic_precision_index = _Verify_dynamic_arg_index_in_range(_Parse_ctx.next_arg_id()); } constexpr void _On_conversion_spec(char _Modifier, _CharT _Type) { // NOTE: same performance note from _Basic_format_specs also applies here if (_Modifier != '\0' && _Modifier != 'E' && _Modifier != 'O') { _THROW(format_error("Invalid modifier specification.")); } if (_Type < 0 || _Type > (numeric_limits::max) ()) { _THROW(format_error("Invalid type specification.")); } _Chrono_spec<_CharT> _Conv_spec{._Modifier = _Modifier, ._Type = static_cast(_Type)}; _Specs._Chrono_specs_list.push_back(_Conv_spec); } constexpr void _On_lit_char(_CharT _Lit_ch) { _Chrono_spec<_CharT> _Lit_char_spec{._Lit_char = _Lit_ch}; _Specs._Chrono_specs_list.push_back(_Lit_char_spec); } private: _Chrono_format_specs<_CharT>& _Specs; _ParseContext& _Parse_ctx; _NODISCARD static constexpr int _Verify_dynamic_arg_index_in_range(const size_t _Idx) { if (_Idx > static_cast((numeric_limits::max) ())) { _THROW(format_error("Dynamic width or precision index too large.")); } return static_cast(_Idx); } }; // assumes that the required '%' at the beginning of a conversion-spec has already been consumed template _Callbacks_type> _NODISCARD constexpr const _CharT* _Parse_conversion_specs( const _CharT* _Begin, const _CharT* _End, _Callbacks_type&& _Callbacks) { if (_Begin == _End || *_Begin == '}') { _THROW(format_error("Invalid format string.")); } char _Mod = '\0'; _CharT _Ch = *_Begin; if (_Ch == 'E' || _Ch == 'O') { // includes modifier _Mod = static_cast(_Ch); ++_Begin; if (_Begin == _End || *_Begin == '}') { _THROW(format_error("Invalid format string - missing type after modifier.")); } } _CharT _Type = *_Begin; _Callbacks._On_conversion_spec(_Mod, _Type); return ++_Begin; } template _Callbacks_type> _NODISCARD constexpr const _CharT* _Parse_chrono_format_specs( const _CharT* _Begin, const _CharT* _End, _Callbacks_type&& _Callbacks) { if (_Begin == _End || *_Begin == '}') { return _Begin; } _Begin = _Parse_align(_Begin, _End, _Callbacks); if (_Begin == _End) { return _Begin; } _Begin = _Parse_width(_Begin, _End, _Callbacks); if (_Begin == _End) { return _Begin; } if (*_Begin == '.') { _Begin = _Parse_precision(_Begin, _End, _Callbacks); if (_Begin == _End) { return _Begin; } } if (*_Begin != '}' && *_Begin != '%') { _THROW(format_error("Invalid format string - chrono-specs must begin with conversion-spec")); } // chrono-spec while (_Begin != _End && *_Begin != '}') { if (*_Begin == '%') { // conversion-spec if (++_Begin == _End) { _THROW(format_error("Invalid format string - missing type after %")); } switch (*_Begin) { case 'n': _Callbacks._On_lit_char('\n'); ++_Begin; break; case 't': _Callbacks._On_lit_char('\t'); ++_Begin; break; case '%': _Callbacks._On_lit_char('%'); ++_Begin; break; default: // some other type _Begin = _Parse_conversion_specs(_Begin, _End, _Callbacks); break; } } else { // literal-char _Callbacks._On_lit_char(*_Begin); ++_Begin; } } return _Begin; } namespace chrono { template struct _Local_time_format_t { local_time<_Duration> _Time; const string* _Abbrev = nullptr; const seconds* _Offset_sec = nullptr; }; template _NODISCARD _Local_time_format_t<_Duration> local_time_format(const local_time<_Duration> _Time, const string* const _Abbrev = nullptr, const seconds* const _Offset_sec = nullptr) { return {_Time, _Abbrev, _Offset_sec}; } // Replacement for %S, as put_time does not honor writing fractional seconds. template void _Write_seconds(basic_ostream<_CharT, _Traits>&, const _Ty&) { _STL_INTERNAL_CHECK(false); } template void _Write_fractional_seconds( basic_ostream<_CharT, _Traits>& _Os, const seconds& _Seconds, const _Precision& _Subseconds) { _Os << _STD format(_STATICALLY_WIDEN(_CharT, "{:02}"), _Seconds.count()); if constexpr (_Fractional_width > 0) { _Os << _STD use_facet>(_Os.getloc()).decimal_point(); if constexpr (treat_as_floating_point_v) { _Os << _STD format( _STATICALLY_WIDEN(_CharT, "{:0{}.0f}"), _STD floor(_Subseconds.count()), _Fractional_width); } else { _Os << _STD format(_STATICALLY_WIDEN(_CharT, "{:0{}}"), _Subseconds.count(), _Fractional_width); } } } template void _Write_seconds(basic_ostream<_CharT, _Traits>& _Os, const hh_mm_ss<_Duration>& _Val) { _Write_fractional_seconds::fractional_width>(_Os, _Val.seconds(), _Val.subseconds()); } template void _Write_seconds(basic_ostream<_CharT, _Traits>& _Os, const time_point<_Clock, _Duration>& _Val) { if constexpr (is_same_v<_Clock, utc_clock>) { const auto _Lsi = _CHRONO get_leap_second_info(_Val); const auto _Dp = _CHRONO floor(_Val - _Lsi.elapsed) + _Lsi.elapsed - seconds{_Lsi.is_leap_second ? 1 : 0}; const hh_mm_ss _Hms{_Val - _Dp}; constexpr auto _Fractional_width = decltype(_Hms)::fractional_width; if (_Lsi.is_leap_second) { _Write_fractional_seconds<_Fractional_width>(_Os, _Hms.seconds() + seconds{60}, _Hms.subseconds()); } else { _Write_fractional_seconds<_Fractional_width>(_Os, _Hms.seconds(), _Hms.subseconds()); } } else { const auto _Dp = _CHRONO floor(_Val); _Write_seconds(_Os, hh_mm_ss{_Val - _Dp}); } } template void _Write_seconds(basic_ostream<_CharT, _Traits>& _Os, const _Local_time_format_t<_Duration>& _Val) { _Write_seconds(_Os, _Val._Time); } template void _Write_seconds(basic_ostream<_CharT, _Traits>& _Os, const duration<_Rep, _Period>& _Val) { const auto _Dp = _CHRONO duration_cast(_Val); _Write_seconds(_Os, hh_mm_ss{_Val - _Dp}); } template _NODISCARD tm _Fill_tm(const _Ty& _Val) { unsigned int _Day = 0; unsigned int _Month = 0; int _Year = 0; int _Yearday = 0; int _Weekday = 0; int _Hours = 0; int _Minutes = 0; int _Seconds = 0; if constexpr (_Is_specialization_v<_Ty, duration>) { const auto _Dp = _CHRONO duration_cast(_Val); return _Fill_tm(hh_mm_ss{_Val - _Dp}); } else if constexpr (_Is_specialization_v<_Ty, _Local_time_format_t>) { return _Fill_tm(_Val._Time); } else if constexpr (is_same_v<_Ty, day>) { _Day = static_cast(_Val); } else if constexpr (is_same_v<_Ty, month>) { _Month = static_cast(_Val); } else if constexpr (is_same_v<_Ty, year>) { _Year = static_cast(_Val); } else if constexpr (is_same_v<_Ty, weekday>) { _Weekday = static_cast(_Val.c_encoding()); } else if constexpr (_Is_any_of_v<_Ty, weekday_indexed, weekday_last>) { _Weekday = static_cast(_Val.weekday().c_encoding()); } else if constexpr (is_same_v<_Ty, month_day>) { _Day = static_cast(_Val.day()); _Month = static_cast(_Val.month()); if (_Val.month() == January) { _Yearday = static_cast(_Day) - 1; } else if (_Val.month() == February) { _Yearday = 31 + static_cast(_Day) - 1; } } else if constexpr (is_same_v<_Ty, month_day_last>) { _Month = static_cast(_Val.month()); _Day = static_cast(_Last_day_table[(_Month - 1) & 0xF]); if (_Val.month() == January) { _Yearday = 30; } } else if constexpr (is_same_v<_Ty, month_weekday>) { _Month = static_cast(_Val.month()); _Weekday = static_cast(_Val.weekday_indexed().weekday().c_encoding()); } else if constexpr (is_same_v<_Ty, month_weekday_last>) { _Month = static_cast(_Val.month()); _Weekday = static_cast(_Val.weekday_last().weekday().c_encoding()); } else if constexpr (is_same_v<_Ty, year_month>) { _Month = static_cast(_Val.month()); _Year = static_cast(_Val.year()); } else if constexpr (_Is_any_of_v<_Ty, year_month_day, year_month_day_last>) { _Day = static_cast(_Val.day()); _Month = static_cast(_Val.month()); _Year = static_cast(_Val.year()); if (_Val.ok()) { const year_month_day& _Ymd = _Val; _Weekday = _Ymd._Calculate_weekday(); _Yearday = (static_cast(_Val) - static_cast(_Val.year() / January / 1)).count(); } } else if constexpr (_Is_any_of_v<_Ty, year_month_weekday, year_month_weekday_last>) { auto _Tm = _Fill_tm(year_month_day{_Val}); _Tm.tm_wday = static_cast(_Val.weekday().c_encoding()); return _Tm; } else if constexpr (_Is_specialization_v<_Ty, hh_mm_ss>) { _Hours = _Val.hours().count(); _Minutes = _Val.minutes().count(); _Seconds = static_cast(_Val.seconds().count()); } else if constexpr (_Is_any_of_v<_Ty, sys_info, local_info>) { return {}; // none of the valid conversion specifiers need tm fields } else if constexpr (_Is_specialization_v<_Ty, time_point>) { const auto _Dp = _CHRONO floor(_Val); const year_month_day _Ymd{_Dp}; const hh_mm_ss _Time{_Val - _Dp}; const auto _Hms = _Fill_tm(_Time); auto _Tm = _Fill_tm(_Ymd); _Tm.tm_sec = _Hms.tm_sec; _Tm.tm_min = _Hms.tm_min; _Tm.tm_hour = _Hms.tm_hour; return _Tm; } tm _Time; _Time.tm_sec = _Seconds; _Time.tm_min = _Minutes; _Time.tm_hour = _Hours; _Time.tm_mday = static_cast(_Day); _Time.tm_mon = static_cast(_Month) - 1; _Time.tm_year = _Year - 1900; _Time.tm_yday = _Yearday; _Time.tm_wday = _Weekday; return _Time; } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const day& _Val) { return _Os << (_Val.ok() ? _STD format(_STATICALLY_WIDEN(_CharT, "{:%d}"), _Val) : _STD format(_STATICALLY_WIDEN(_CharT, "{:%d} is not a valid day"), _Val)); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const month& _Val) { return _Os << (_Val.ok() ? _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{:%b}"), _Val) : _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{} is not a valid month"), static_cast(_Val))); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const year& _Val) { return _Os << (_Val.ok() ? _STD format(_STATICALLY_WIDEN(_CharT, "{:%Y}"), _Val) : _STD format(_STATICALLY_WIDEN(_CharT, "{:%Y} is not a valid year"), _Val)); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const weekday& _Val) { return _Os << (_Val.ok() ? _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{:%a}"), _Val) : _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{} is not a valid weekday"), _Val.c_encoding())); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const weekday_indexed& _Val) { const auto _Idx = _Val.index(); return _Os << (_Idx >= 1 && _Idx <= 5 ? _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{}[{}]"), _Val.weekday(), _Idx) : _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{}[{} is not a valid index]"), _Val.weekday(), _Idx)); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const weekday_last& _Val) { return _Os << _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{}[last]"), _Val.weekday()); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const month_day& _Val) { return _Os << _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{}/{}"), _Val.month(), _Val.day()); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const month_day_last& _Val) { return _Os << _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{}/last"), _Val.month()); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const month_weekday& _Val) { return _Os << _STD format( _Os.getloc(), _STATICALLY_WIDEN(_CharT, "{}/{}"), _Val.month(), _Val.weekday_indexed()); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const month_weekday_last& _Val) { return _Os << _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{}/{}"), _Val.month(), _Val.weekday_last()); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const year_month& _Val) { return _Os << _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{}/{}"), _Val.year(), _Val.month()); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const year_month_day& _Val) { return _Os << (_Val.ok() ? _STD format(_STATICALLY_WIDEN(_CharT, "{:%F}"), _Val) : _STD format(_STATICALLY_WIDEN(_CharT, "{:%F} is not a valid date"), _Val)); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const year_month_day_last& _Val) { return _Os << _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{}/{}"), _Val.year(), _Val.month_day_last()); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const year_month_weekday& _Val) { return _Os << _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{}/{}/{}"), _Val.year(), _Val.month(), _Val.weekday_indexed()); } template basic_ostream<_CharT, _Traits>& operator<<( basic_ostream<_CharT, _Traits>& _Os, const year_month_weekday_last& _Val) { return _Os << _STD format( _Os.getloc(), _STATICALLY_WIDEN(_CharT, "{}/{}/{}"), _Val.year(), _Val.month(), _Val.weekday_last()); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const hh_mm_ss<_Duration>& _Val) { return _Os << _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{:%T}"), _Val); } #pragma warning(push) #pragma warning(disable : 4365) // 'argument': conversion from 'char' to 'const wchar_t', signed/unsigned mismatch template _NODISCARD decltype(auto) _Widen_string(const string& _Str) { if constexpr (is_same_v<_CharT, char>) { return _Str; } else { return wstring{_Str.begin(), _Str.end()}; // TRANSITION, should probably use ctype::widen } } #pragma warning(pop) template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const sys_info& _Val) { return _Os << _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "begin: {}, end: {}, offset: {}, save: {}, abbrev: {}"), // _Val.begin, _Val.end, _Val.offset, _Val.save, _Widen_string<_CharT>(_Val.abbrev)); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const local_info& _Val) { switch (_Val.result) { case local_info::unique: return _Os << _STD format(_Os.getloc(), // _STATICALLY_WIDEN(_CharT, "result: unique, first: ({})"), // _Val.first); case local_info::nonexistent: return _Os << _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "result: nonexistent, first: ({}), second: ({})"), // _Val.first, _Val.second); case local_info::ambiguous: return _Os << _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "result: ambiguous, first: ({}), second: ({})"), // _Val.first, _Val.second); default: return _Os << _STD format(_Os.getloc(), // _STATICALLY_WIDEN(_CharT, "result: {}, first: ({}), second: ({})"), // _Val.result, _Val.first, _Val.second); } } template // clang-format off requires (!treat_as_floating_point_v && _Duration{1} < days{1}) basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const sys_time<_Duration>& _Val) { // clang-format on const auto _Dp = _CHRONO floor(_Val); return _Os << _STD format( _Os.getloc(), _STATICALLY_WIDEN(_CharT, "{} {}"), year_month_day{_Dp}, hh_mm_ss{_Val - _Dp}); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const sys_days& _Val) { return _Os << year_month_day{_Val}; } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const utc_time<_Duration>& _Val) { return _Os << _STD format(_STATICALLY_WIDEN(_CharT, "{:%F %T}"), _Val); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const tai_time<_Duration>& _Val) { return _Os << _STD format(_STATICALLY_WIDEN(_CharT, "{:%F %T}"), _Val); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const gps_time<_Duration>& _Val) { return _Os << _STD format(_STATICALLY_WIDEN(_CharT, "{:%F %T}"), _Val); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const file_time<_Duration>& _Val) { return _Os << _STD format(_STATICALLY_WIDEN(_CharT, "{:%F %T}"), _Val); } template basic_ostream<_CharT, _Traits>& operator<<(basic_ostream<_CharT, _Traits>& _Os, const local_time<_Duration>& _Val) { return _Os << sys_time<_Duration>{_Val.time_since_epoch()}; } template basic_ostream<_CharT, _Traits>& operator<<( basic_ostream<_CharT, _Traits>& _Os, const _Local_time_format_t<_Duration>& _Val) { // Doesn't appear in the Standard, but allowed by N4885 [global.functions]/2. // Implements N4885 [time.zone.zonedtime.nonmembers]/2 for zoned_time. return _Os << _STD format(_Os.getloc(), _STATICALLY_WIDEN(_CharT, "{:%F %T %Z}"), _Val); } template basic_ostream<_CharT, _Traits>& operator<<( basic_ostream<_CharT, _Traits>& _Os, const zoned_time<_Duration, _TimeZonePtr>& _Val) { const auto _Info = _Val.get_info(); return _Os << _Local_time_format_t<_Duration>{_Val.get_local_time(), &_Info.abbrev}; } template struct _Chrono_formatter { _Chrono_formatter() = default; explicit _Chrono_formatter(const basic_string_view<_CharT> _Time_zone_abbreviation_) : _Time_zone_abbreviation{_Time_zone_abbreviation_} {} template _NODISCARD auto _Parse(basic_format_parse_context<_CharT>& _Parse_ctx) { _Chrono_specs_setter<_CharT, basic_format_parse_context<_CharT>> _Callback{_Specs, _Parse_ctx}; const auto _It = _Parse_chrono_format_specs(_Parse_ctx._Unchecked_begin(), _Parse_ctx._Unchecked_end(), _Callback); const auto _Res_iter = _Parse_ctx.begin() + (_It - _Parse_ctx._Unchecked_begin()); if (_It != _Parse_ctx._Unchecked_end() && *_It != '}') { _THROW(format_error("Missing '}' in format string.")); } if constexpr (_Is_specialization_v<_Ty, duration>) { if constexpr (!treat_as_floating_point_v) { if (_Specs._Precision != -1) { _THROW(format_error("Precision specification invalid for chrono::duration type with " "integral representation type, see N4885 [time.format]/1.")); } } } else { if (_Specs._Precision != -1) { _THROW(format_error("Precision specification invalid for non-chrono::duration type, " "see N4885 [time.format]/1.")); } } for (const auto& _Spec : _Specs._Chrono_specs_list) { if (_Spec._Type != '\0' && !_Is_valid_type<_Ty>(_Spec._Type)) { _THROW(format_error("Invalid type.")); } _Check_modifier(_Spec._Type, _Spec._Modifier); } return _Res_iter; } static void _Check_modifier(const char _Type, const char _Modifier) { if (_Modifier == '\0') { return; } enum _Allowed_bit : uint8_t { _E_mod = 1, _O_mod = 2, _EO_mod = _E_mod | _O_mod }; struct _Table_entry { char _Type; _Allowed_bit _Allowed; }; static constexpr _Table_entry _Table[] = { {'c', _E_mod}, {'C', _E_mod}, {'d', _O_mod}, {'e', _O_mod}, {'H', _O_mod}, {'I', _O_mod}, {'m', _O_mod}, {'M', _O_mod}, {'S', _O_mod}, {'u', _O_mod}, {'U', _O_mod}, {'V', _O_mod}, {'w', _O_mod}, {'W', _O_mod}, {'x', _E_mod}, {'X', _E_mod}, {'y', _EO_mod}, {'Y', _E_mod}, {'z', _EO_mod}, }; const _Allowed_bit _Mod = _Modifier == 'E' ? _E_mod : _O_mod; if (auto _It = _RANGES find(_Table, _Type, &_Table_entry::_Type); _It != _STD end(_Table)) { if (_It->_Allowed & _Mod) { return; } } _THROW(format_error("Incompatible modifier for type")); } template _NODISCARD static constexpr bool _Is_valid_type(const char _Type) noexcept { if constexpr (_Is_specialization_v<_Ty, duration>) { return _Type == 'j' || _Type == 'q' || _Type == 'Q' || _Is_valid_type>(_Type); } else if constexpr (is_same_v<_Ty, day>) { return _Type == 'd' || _Type == 'e'; } else if constexpr (is_same_v<_Ty, month>) { return _Type == 'b' || _Type == 'B' || _Type == 'h' || _Type == 'm'; } else if constexpr (is_same_v<_Ty, year>) { return _Type == 'Y' || _Type == 'y' || _Type == 'C'; } else if constexpr (_Is_any_of_v<_Ty, weekday, weekday_indexed, weekday_last>) { return _Type == 'a' || _Type == 'A' || _Type == 'u' || _Type == 'w'; } else if constexpr (_Is_any_of_v<_Ty, month_day, month_day_last>) { return _Type == 'j' || _Is_valid_type(_Type) || _Is_valid_type(_Type); } else if constexpr (_Is_any_of_v<_Ty, month_weekday, month_weekday_last>) { return _Is_valid_type(_Type) || _Is_valid_type(_Type); } else if constexpr (is_same_v<_Ty, year_month>) { return _Type == 'g' || _Type == 'G' || _Is_valid_type(_Type) || _Is_valid_type(_Type); } else if constexpr (_Is_any_of_v<_Ty, year_month_day, year_month_day_last, year_month_weekday, year_month_weekday_last>) { return _Type == 'D' || _Type == 'F' || _Type == 'g' || _Type == 'G' || _Type == 'j' || _Type == 'U' || _Type == 'V' || _Type == 'W' || _Is_valid_type(_Type) || _Is_valid_type(_Type) || _Is_valid_type(_Type) || _Is_valid_type(_Type); } else if constexpr (_Is_specialization_v<_Ty, hh_mm_ss>) { return _Type == 'H' || _Type == 'I' || _Type == 'M' || _Type == 'S' || _Type == 'r' || _Type == 'R' || _Type == 'T' || _Type == 'p'; } else if constexpr (_Is_any_of_v<_Ty, sys_info, local_info>) { return _Type == 'z' || _Type == 'Z'; } else if constexpr (_Is_specialization_v<_Ty, time_point>) { if constexpr (!is_same_v) { if (_Type == 'z' || _Type == 'Z') { return true; } } return _Type == 'c' || _Type == 'x' || _Type == 'X' || _Is_valid_type(_Type) || _Is_valid_type>(_Type); } else if constexpr (_Is_specialization_v<_Ty, _Local_time_format_t>) { return _Type == 'z' || _Type == 'Z' || _Is_valid_type(_Type); } else { static_assert(_Always_false<_Ty>, "should be unreachable"); } } template _NODISCARD auto _Write(_FormatContext& _FormatCtx, const _Ty& _Val, const tm& _Time) { basic_ostringstream<_CharT> _Stream; if (_Specs._Chrono_specs_list.empty()) { _Stream << _Val; // N4885 [time.format]/6 } else { _Stream.imbue(_FormatCtx.locale()); if constexpr (_Is_specialization_v<_Ty, hh_mm_ss>) { if (_Val.is_negative()) { _Stream << _CharT{'-'}; } } else if constexpr (_Is_specialization_v<_Ty, duration>) { if (_Val < _Ty::zero()) { _Stream << _CharT{'-'}; } } for (const auto& _Spec : _Specs._Chrono_specs_list) { if (_Spec._Lit_char != _CharT{'\0'}) { _Stream << _Spec._Lit_char; continue; } // We need to manually do certain writes, either because the specification is different from // put_time or custom logic is needed. if (_Custom_write(_Stream, _Spec, _Time, _Val)) { continue; } _Validate_specifiers(_Spec, _Val); _CharT _Fmt_str[4]; _Stream << _STD put_time<_CharT>(&_Time, _Fmt_string(_Spec, _Fmt_str)); } } int _Estimated_width = -1; (void) _Measure_string_prefix(_Stream.view(), _Estimated_width); return _Write_aligned(_STD move(_FormatCtx.out()), _Estimated_width, _Specs, _Fmt_align::_Left, [&](auto _Out) { return _Fmt_write(_STD move(_Out), _Stream.view()); }); } // This echoes the functionality of put_time, but is able to handle invalid dates (when !ok()) since the // Standard mandates that invalid dates still be formatted properly. For example, put_time isn't able to handle // a tm_mday of 40, but format("{:%d}", day{40}) should return "40" and operator<< for day prints // "40 is not a valid day". template bool _Custom_write( basic_ostream<_CharT>& _Os, const _Chrono_spec<_CharT>& _Spec, const tm& _Time, const _Ty& _Val) { if constexpr (is_same_v<_Ty, local_info>) { if (_Val.result != local_info::unique) { _THROW(format_error("Cannot print non-unique local_info")); } } const auto _Year = _Time.tm_year + 1900; const auto _Month = _Time.tm_mon + 1; const bool _Has_modifier = _Spec._Modifier != '\0'; switch (_Spec._Type) { case 'd': // Print days as a decimal, even if invalid. case 'e': // Most months have a proper last day, but February depends on the year. if constexpr (is_same_v<_Ty, month_day_last>) { if (_Val.month() == February) { _THROW(format_error("Cannot print the last day of February without a year")); } if (!_Val.ok()) { return false; } } if (_Has_modifier) { return false; } if (_Time.tm_mday < 10) { _Os << (_Spec._Type == 'd' ? _CharT{'0'} : _CharT{' '}); } _Os << _Time.tm_mday; return true; case 'g': case 'G': if constexpr (is_same_v<_Ty, year_month>) { if (_Val.month() == January || _Val.month() == December) { _THROW(format_error( "The ISO week-based year for a year_month of January or December is ambiguous.")); } if (!_Val.ok()) { _THROW(format_error("The ISO week-based year for an out-of-bounds year_month is ambiguous.")); } const char _Gregorian_type = _Spec._Type == 'g' ? 'y' : 'Y'; _CharT _Fmt_str[4]; _Os << _STD put_time(&_Time, _Fmt_string({._Type = _Gregorian_type}, _Fmt_str)); return true; } return false; case 'r': // put_time uses _Strftime in order to bypass reference-counting that locale uses. This function // takes the locale information by pointer, but the pointer (from _Gettnames) returns a copy. // _Strftime delegates to other functions but eventually (for the C locale) has the %r specifier // rewritten. It checks for the locale by comparing pointers, which do not compare equal as we have // a copy of the pointer instead of the original. Therefore, we replace %r for the C locale // ourselves. if (_Os.getloc() == locale::classic()) { _Os << _STD put_time(&_Time, _STATICALLY_WIDEN(_CharT, "%I:%M:%S %p")); return true; } return false; case 'j': if constexpr (_Is_specialization_v<_Ty, duration>) { _Os << _STD abs(_CHRONO duration_cast(_Val).count()); return true; } return false; case 'q': if constexpr (_Is_specialization_v<_Ty, duration>) { _Write_unit_suffix(_Os); } return true; case 'Q': if constexpr (_Is_specialization_v<_Ty, duration>) { _Os << _STD abs(_Val.count()); } return true; case 'm': // Print months as a decimal, even if invalid. if (_Has_modifier) { return false; } if (_Month < 10) { _Os << _CharT{'0'}; } _Os << _Month; return true; case 'Y': // Print years as a decimal, even if invalid. if (_Has_modifier) { return false; } if (_Year < 0) { _Os << _CharT{'-'}; } _Os << _STD format(_STATICALLY_WIDEN(_CharT, "{:04}"), _STD abs(_Year)); return true; case 'y': // Print the two-digit year as a decimal, even if invalid. if (_Has_modifier) { return false; } _Os << _STD format( _STATICALLY_WIDEN(_CharT, "{:02}"), _Time_parse_fields::_Decompose_year(_Year).second); return true; case 'C': // Print the century as a decimal, even if invalid. if (_Has_modifier) { return false; } if (_Year < 0) { _Os << _CharT{'-'}; } _Os << _STD format(_STATICALLY_WIDEN(_CharT, "{:02}"), _STD abs(_Time_parse_fields::_Decompose_year(_Year).first) / 100); return true; case 'F': // Print YMD even if invalid. _Custom_write(_Os, {._Type = 'Y'}, _Time, _Val); _Os << _CharT{'-'}; _Custom_write(_Os, {._Type = 'm'}, _Time, _Val); _Os << _CharT{'-'}; _Custom_write(_Os, {._Type = 'd'}, _Time, _Val); return true; case 'D': // Print YMD even if invalid. _Custom_write(_Os, {._Type = 'm'}, _Time, _Val); _Os << _CharT{'/'}; _Custom_write(_Os, {._Type = 'd'}, _Time, _Val); _Os << _CharT{'/'}; _Custom_write(_Os, {._Type = 'y'}, _Time, _Val); return true; case 'T': // Alias for %H:%M:%S but we need to rewrite %S to display fractions of a second. _Validate_specifiers({._Type = 'H'}, _Val); _Os << _STD put_time(&_Time, _STATICALLY_WIDEN(_CharT, "%H:%M:")); [[fallthrough]]; case 'S': if (_Has_modifier) { return false; } _Write_seconds(_Os, _Val); return true; case 'Z': if constexpr (is_same_v<_Ty, sys_info>) { _Os << _Widen_string<_CharT>(_Val.abbrev); } else if constexpr (is_same_v<_Ty, local_info>) { _Os << _Widen_string<_CharT>(_Val.first.abbrev); } else if constexpr (_Is_specialization_v<_Ty, _Local_time_format_t>) { if (_Val._Abbrev == nullptr) { _THROW(format_error("Cannot print local-time-format-t with null abbrev.")); } _Os << _Widen_string<_CharT>(*_Val._Abbrev); } else { _Os << _Time_zone_abbreviation; } return true; case 'z': { hh_mm_ss _Offset; if constexpr (is_same_v<_Ty, sys_info>) { _Offset = hh_mm_ss{_Val.offset}; } else if constexpr (is_same_v<_Ty, local_info>) { _Offset = hh_mm_ss{_Val.first.offset}; } else if constexpr (_Is_specialization_v<_Ty, _Local_time_format_t>) { if (_Val._Offset_sec == nullptr) { _THROW(format_error("Cannot print local-time-format-t with null offset_sec.")); } _Offset = hh_mm_ss{*_Val._Offset_sec}; } else { _Offset = hh_mm_ss{}; } const auto _Sign = _Offset.is_negative() ? _CharT{'-'} : _CharT{'+'}; const auto _Separator = _Has_modifier ? _STATICALLY_WIDEN(_CharT, ":") : _STATICALLY_WIDEN(_CharT, ""); _Os << _STD format(_STATICALLY_WIDEN(_CharT, "{}{:02}{}{:02}"), _Sign, _Offset.hours().count(), _Separator, _Offset.minutes().count()); return true; } default: return false; } } template static void _Validate_specifiers(const _Chrono_spec<_CharT>& _Spec, const _Ty& _Val) { // clang-format off if constexpr (_Is_specialization_v<_Ty, duration> || is_same_v<_Ty, sys_info> || _Is_specialization_v<_Ty, time_point> || _Is_specialization_v<_Ty, _Local_time_format_t>) { return; } // clang-format on if constexpr (_Is_specialization_v<_Ty, hh_mm_ss>) { if (_Spec._Type == 'H' && _Val.hours() >= hours{24}) { _THROW(format_error("Cannot localize hh_mm_ss with an absolute value of 24 hours or more.")); } return; } constexpr bool _Is_ymd = _Is_any_of_v<_Ty, year_month_day, year_month_day_last, year_month_weekday, year_month_weekday_last>; const auto _Validate = [&] { switch (_Spec._Type) { case 'a': case 'A': case 'u': case 'w': if constexpr (_Is_any_of_v<_Ty, weekday, weekday_last>) { return _Val.ok(); } else if constexpr (_Is_any_of_v<_Ty, weekday_indexed, year_month_weekday, year_month_weekday_last>) { return _Val.weekday().ok(); } else if constexpr (is_same_v<_Ty, month_weekday>) { return _Val.weekday_indexed().weekday().ok(); } else if constexpr (is_same_v<_Ty, month_weekday_last>) { return _Val.weekday_last().ok(); } else if constexpr (_Is_any_of_v<_Ty, year_month_day, year_month_day_last>) { return _Val.ok(); } break; case 'b': case 'B': case 'h': case 'm': if constexpr (is_same_v<_Ty, month>) { return _Val.ok(); } else if constexpr (_Is_any_of_v<_Ty, month_day, month_day_last, month_weekday, month_weekday_last, year_month> || _Is_ymd) { return _Val.month().ok(); } break; case 'C': case 'y': case 'Y': if constexpr (is_same_v<_Ty, year>) { return _Val.ok(); } else if constexpr (_Is_any_of_v<_Ty, year_month> || _Is_ymd) { return _Val.year().ok(); } break; case 'd': case 'e': if constexpr (_Is_any_of_v<_Ty, day, month_day_last>) { return _Val.ok(); } else if constexpr (is_same_v<_Ty, month_day>) { return _Val.day().ok(); } else if constexpr (_Is_ymd) { const year_month_day& _Ymd{_Val}; return _Ymd.day().ok(); } break; case 'D': case 'F': if constexpr (_Has_ok<_Ty>) { return _Val.ok(); } break; case 'j': if constexpr (is_same_v<_Ty, month_day>) { if (_Val.month() > February) { _THROW(format_error("The day of year for a month_day past February is ambiguous.")); } return true; } else if constexpr (is_same_v<_Ty, month_day_last>) { if (_Val.month() >= February) { _THROW( format_error("The day of year for a month_day_last other than January is ambiguous")); } return true; } else if constexpr (_Is_ymd) { return _Val.ok(); } break; case 'g': case 'G': case 'U': case 'V': case 'W': if constexpr (_Is_ymd) { return _Val.ok(); } break; default: if constexpr (_Has_ok<_Ty>) { return _Val.ok(); } return true; } _STL_INTERNAL_CHECK(false); return false; }; if (!_Validate()) { _THROW(format_error("Cannot localize out-of-bounds time point.")); } } _NODISCARD static const _CharT* _Fmt_string(const _Chrono_spec<_CharT>& _Spec, _CharT (&_Fmt_str)[4]) { size_t _Next_idx = 0; _Fmt_str[_Next_idx++] = _CharT{'%'}; if (_Spec._Modifier != '\0') { _Fmt_str[_Next_idx++] = static_cast<_CharT>(_Spec._Modifier); } _Fmt_str[_Next_idx++] = static_cast<_CharT>(_Spec._Type); _Fmt_str[_Next_idx] = _CharT{'\0'}; return _Fmt_str; } _Chrono_format_specs<_CharT> _Specs{}; basic_string_view<_CharT> _Time_zone_abbreviation{}; }; } // namespace chrono template struct _Fill_tm_formatter { auto parse(basic_format_parse_context<_CharT>& _Parse_ctx) { return _Impl.template _Parse<_Ty>(_Parse_ctx); } template auto format(const _Ty& _Val, _FormatContext& _FormatCtx) { return _Impl._Write(_FormatCtx, _Val, _Fill_tm(_Val)); } private: _CHRONO _Chrono_formatter<_CharT> _Impl; }; template struct formatter<_CHRONO duration<_Rep, _Period>, _CharT> : _Fill_tm_formatter<_CHRONO duration<_Rep, _Period>, _CharT> {}; template struct formatter<_CHRONO day, _CharT> // : _Fill_tm_formatter<_CHRONO day, _CharT> {}; template struct formatter<_CHRONO month, _CharT> // : _Fill_tm_formatter<_CHRONO month, _CharT> {}; template struct formatter<_CHRONO year, _CharT> // : _Fill_tm_formatter<_CHRONO year, _CharT> {}; template struct formatter<_CHRONO weekday, _CharT> // : _Fill_tm_formatter<_CHRONO weekday, _CharT> {}; template struct formatter<_CHRONO weekday_indexed, _CharT> // : _Fill_tm_formatter<_CHRONO weekday_indexed, _CharT> {}; template struct formatter<_CHRONO weekday_last, _CharT> // : _Fill_tm_formatter<_CHRONO weekday_last, _CharT> {}; template struct formatter<_CHRONO month_day, _CharT> // : _Fill_tm_formatter<_CHRONO month_day, _CharT> {}; template struct formatter<_CHRONO month_day_last, _CharT> // : _Fill_tm_formatter<_CHRONO month_day_last, _CharT> {}; template struct formatter<_CHRONO month_weekday, _CharT> // : _Fill_tm_formatter<_CHRONO month_weekday, _CharT> {}; template struct formatter<_CHRONO month_weekday_last, _CharT> // : _Fill_tm_formatter<_CHRONO month_weekday_last, _CharT> {}; template struct formatter<_CHRONO year_month, _CharT> // : _Fill_tm_formatter<_CHRONO year_month, _CharT> {}; template struct formatter<_CHRONO year_month_day, _CharT> // : _Fill_tm_formatter<_CHRONO year_month_day, _CharT> {}; template struct formatter<_CHRONO year_month_day_last, _CharT> // : _Fill_tm_formatter<_CHRONO year_month_day_last, _CharT> {}; template struct formatter<_CHRONO year_month_weekday, _CharT> // : _Fill_tm_formatter<_CHRONO year_month_weekday, _CharT> {}; template struct formatter<_CHRONO year_month_weekday_last, _CharT> : _Fill_tm_formatter<_CHRONO year_month_weekday_last, _CharT> {}; template struct formatter<_CHRONO hh_mm_ss<_CHRONO duration<_Rep, _Period>>, _CharT> : _Fill_tm_formatter<_CHRONO hh_mm_ss<_CHRONO duration<_Rep, _Period>>, _CharT> {}; template struct formatter<_CHRONO sys_info, _CharT> // : _Fill_tm_formatter<_CHRONO sys_info, _CharT> {}; template struct formatter<_CHRONO local_info, _CharT> // : _Fill_tm_formatter<_CHRONO local_info, _CharT> {}; template struct formatter<_CHRONO sys_time<_Duration>, _CharT> { auto parse(basic_format_parse_context<_CharT>& _Parse_ctx) { return _Impl.template _Parse<_CHRONO sys_time<_Duration>>(_Parse_ctx); } template auto format(const _CHRONO sys_time<_Duration>& _Val, _FormatContext& _FormatCtx) { return _Impl._Write(_FormatCtx, _Val, _Fill_tm(_Val)); } private: _CHRONO _Chrono_formatter<_CharT> _Impl{_STATICALLY_WIDEN(_CharT, "UTC")}; }; template struct formatter<_CHRONO utc_time<_Duration>, _CharT> { auto parse(basic_format_parse_context<_CharT>& _Parse_ctx) { return _Impl.template _Parse<_CHRONO utc_time<_Duration>>(_Parse_ctx); } template auto format(const _CHRONO utc_time<_Duration>& _Val, _FormatContext& _FormatCtx) { const auto _Sys = _CHRONO utc_clock::to_sys(_Val); return _Impl._Write(_FormatCtx, _Val, _Fill_tm(_Sys)); } private: _CHRONO _Chrono_formatter<_CharT> _Impl{_STATICALLY_WIDEN(_CharT, "UTC")}; }; template struct formatter<_CHRONO tai_time<_Duration>, _CharT> { auto parse(basic_format_parse_context<_CharT>& _Parse_ctx) { return _Impl.template _Parse<_CHRONO tai_time<_Duration>>(_Parse_ctx); } template auto format(const _CHRONO tai_time<_Duration>& _Val, _FormatContext& _FormatCtx) { using namespace chrono; using _Common = common_type_t<_Duration, days>; // slightly optimize by performing conversion at compile time constexpr _Common _Offset{sys_days{year{1970} / January / 1} - sys_days{year{1958} / January / 1}}; const auto _Sys = sys_time<_Duration>{_Val.time_since_epoch()} - _Offset; return _Impl._Write(_FormatCtx, _Val, _Fill_tm(_Sys)); } private: _CHRONO _Chrono_formatter<_CharT> _Impl{_STATICALLY_WIDEN(_CharT, "TAI")}; }; template struct formatter<_CHRONO gps_time<_Duration>, _CharT> { auto parse(basic_format_parse_context<_CharT>& _Parse_ctx) { return _Impl.template _Parse<_CHRONO gps_time<_Duration>>(_Parse_ctx); } template auto format(const _CHRONO gps_time<_Duration>& _Val, _FormatContext& _FormatCtx) { using namespace chrono; using _Common = common_type_t<_Duration, days>; // slightly optimize by performing conversion at compile time constexpr _Common _Offset{sys_days{year{1980} / January / Sunday[1]} - sys_days{year{1970} / January / 1}}; const auto _Sys = sys_time<_Duration>{_Val.time_since_epoch()} + _Offset; return _Impl._Write(_FormatCtx, _Val, _Fill_tm(_Sys)); } private: _CHRONO _Chrono_formatter<_CharT> _Impl{_STATICALLY_WIDEN(_CharT, "GPS")}; }; template struct formatter<_CHRONO file_time<_Duration>, _CharT> { auto parse(basic_format_parse_context<_CharT>& _Parse_ctx) { return _Impl.template _Parse<_CHRONO file_time<_Duration>>(_Parse_ctx); } template auto format(const _CHRONO file_time<_Duration>& _Val, _FormatContext& _FormatCtx) { const auto _Utc = _CHRONO file_clock::to_utc(_Val); const auto _Sys = _CHRONO utc_clock::to_sys(_Utc); return _Impl._Write(_FormatCtx, _Utc, _Fill_tm(_Sys)); } private: _CHRONO _Chrono_formatter<_CharT> _Impl{_STATICALLY_WIDEN(_CharT, "UTC")}; }; template struct formatter<_CHRONO local_time<_Duration>, _CharT> // : _Fill_tm_formatter<_CHRONO local_time<_Duration>, _CharT> {}; template struct formatter<_CHRONO _Local_time_format_t<_Duration>, _CharT> : _Fill_tm_formatter<_CHRONO _Local_time_format_t<_Duration>, _CharT> {}; template struct formatter<_CHRONO zoned_time<_Duration, _TimeZonePtr>, _CharT> : formatter<_CHRONO _Local_time_format_t<_Duration>, _CharT> { template auto format(const _CHRONO zoned_time<_Duration, _TimeZonePtr>& _Val, _FormatContext& _FormatCtx) { using _Mybase = formatter<_CHRONO _Local_time_format_t<_Duration>, _CharT>; const auto _Info = _Val.get_info(); return _Mybase::format({_Val.get_local_time(), &_Info.abbrev, &_Info.offset}, _FormatCtx); } }; namespace chrono { template _NODISCARD string nonexistent_local_time::_Make_string(const local_time<_Duration>& _Tp, const local_info& _Info) { ostringstream _Os; _Os << _Tp << " is in a gap between\n" << local_seconds{_Info.first.end.time_since_epoch()} + _Info.first.offset << ' ' << _Info.first.abbrev << " and\n" << local_seconds{_Info.second.begin.time_since_epoch()} + _Info.second.offset << ' ' << _Info.second.abbrev << " which are both equivalent to\n" << _Info.first.end << " UTC"; return _STD move(_Os).str(); } template _NODISCARD string ambiguous_local_time::_Make_string(const local_time<_Duration>& _Tp, const local_info& _Info) { ostringstream _Os; _Os << _Tp << " is ambiguous. It could be\n" << _Tp << ' ' << _Info.first.abbrev << " == " << _Tp - _Info.first.offset << " UTC or\n" << _Tp << ' ' << _Info.second.abbrev << " == " << _Tp - _Info.second.offset << " UTC"; return _STD move(_Os).str(); } } // namespace chrono #endif // __cpp_lib_format template _NODISCARD bool _To_xtime_10_day_clamped(_CSTD xtime& _Xt, const _CHRONO duration<_Rep, _Period>& _Rel_time) noexcept( is_arithmetic_v<_Rep>) { // Convert duration to xtime, maximum 10 days from now, returns whether clamping occurred. // If clamped, timeouts will be transformed into spurious non-timeout wakes, due to ABI restrictions where // the other side of the DLL boundary overflows int32_t milliseconds. // Every function calling this one is TRANSITION, ABI constexpr _CHRONO nanoseconds _Ten_days{_CHRONO hours{24} * 10}; constexpr _CHRONO duration _Ten_days_d{_Ten_days}; _CHRONO nanoseconds _Tx0 = _CHRONO system_clock::now().time_since_epoch(); const bool _Clamped = _Ten_days_d < _Rel_time; if (_Clamped) { _Tx0 += _Ten_days; } else { _Tx0 += _CHRONO duration_cast<_CHRONO nanoseconds>(_Rel_time); } const auto _Whole_seconds = _CHRONO duration_cast<_CHRONO seconds>(_Tx0); _Xt.sec = _Whole_seconds.count(); _Tx0 -= _Whole_seconds; _Xt.nsec = static_cast(_Tx0.count()); return _Clamped; } inline namespace literals { inline namespace chrono_literals { _NODISCARD constexpr _CHRONO hours operator"" h(unsigned long long _Val) noexcept /* strengthened */ { return _CHRONO hours(_Val); } _NODISCARD constexpr _CHRONO duration> operator"" h(long double _Val) noexcept /* strengthened */ { return _CHRONO duration>(_Val); } _NODISCARD constexpr _CHRONO minutes(operator"" min)(unsigned long long _Val) noexcept /* strengthened */ { return _CHRONO minutes(_Val); } _NODISCARD constexpr _CHRONO duration>(operator"" min)(long double _Val) noexcept /* strengthened */ { return _CHRONO duration>(_Val); } _NODISCARD constexpr _CHRONO seconds operator"" s(unsigned long long _Val) noexcept /* strengthened */ { return _CHRONO seconds(_Val); } _NODISCARD constexpr _CHRONO duration operator"" s(long double _Val) noexcept /* strengthened */ { return _CHRONO duration(_Val); } _NODISCARD constexpr _CHRONO milliseconds operator"" ms(unsigned long long _Val) noexcept /* strengthened */ { return _CHRONO milliseconds(_Val); } _NODISCARD constexpr _CHRONO duration operator"" ms(long double _Val) noexcept /* strengthened */ { return _CHRONO duration(_Val); } _NODISCARD constexpr _CHRONO microseconds operator"" us(unsigned long long _Val) noexcept /* strengthened */ { return _CHRONO microseconds(_Val); } _NODISCARD constexpr _CHRONO duration operator"" us(long double _Val) noexcept /* strengthened */ { return _CHRONO duration(_Val); } _NODISCARD constexpr _CHRONO nanoseconds operator"" ns(unsigned long long _Val) noexcept /* strengthened */ { return _CHRONO nanoseconds(_Val); } _NODISCARD constexpr _CHRONO duration operator"" ns(long double _Val) noexcept /* strengthened */ { return _CHRONO duration(_Val); } #if _HAS_CXX20 _NODISCARD constexpr _CHRONO day operator"" d(unsigned long long _Day) noexcept { return _CHRONO day{static_cast(_Day)}; } _NODISCARD constexpr _CHRONO year operator"" y(unsigned long long _Year) noexcept { return _CHRONO year{static_cast(_Year)}; } #endif // _HAS_CXX20 } // namespace chrono_literals } // namespace literals namespace chrono { using namespace literals::chrono_literals; } // namespace chrono #undef _STATICALLY_WIDEN _STD_END #pragma pop_macro("new") _STL_RESTORE_CLANG_WARNINGS #pragma warning(pop) #pragma pack(pop) #endif // _STL_COMPILER_PREPROCESSOR #endif // _CHRONO_ c++-annotations-12.5.0/yo/namespaces/filesystem/examples/tosys/demo.cc0000664000175000017500000000237014624637133024667 0ustar frankfrank#include #include #include #include #include "clocktimeconv" using namespace std; using namespace chrono; using namespace filesystem; using namespace FBB; int main(int argc, char **argv) try { error_code ec; // comment out the 2nd clock_time_conversion template and you get the // first: time_t seconds = system_clock::to_time_t( clock_time_conversion{}( system_clock::now() ) ); cout << put_time(localtime(&seconds), "%c") << '\n'; auto sysTime = __file_clock::to_sys(__file_clock::now()); time_t sysSecs = system_clock::to_time_t(sysTime); cout << put_time(localtime(&sysSecs), "%c") << '\n'; // seconds = system_clock::to_time_t( // clock_time_conversion{}( // __file_clock::now() // ) // ); // // cout << put_time(localtime(&seconds), "%c") << '\n'; } catch (exception const &exc) { cout << exc.what() << '\n'; } c++-annotations-12.5.0/yo/namespaces/filesystem/examples/tosys/clocktimeconv0000644000175000017500000000427714466730207026225 0ustar frankfrank#ifndef INCLUDED_CLOCKTIMECONV_ #define INCLUDED_CLOCKTIMECONV_ #include namespace std { namespace chrono { template struct clock_time_conversion {}; template struct clock_time_conversion { template [[nodiscard]] time_point operator() (time_point const & timePoint) const noexcept(is_arithmetic::value) // strengthened { std::cout << "clock_time_conversion 1\n"; return timePoint; } }; template <> struct clock_time_conversion { template [[nodiscard]] sys_time operator()( sys_time const &timePoint) const noexcept(is_arithmetic::value) // strengthened { std::cout << "clock_time_conversion 2\n"; return timePoint; } }; // No utc_clock in chrono. // ======================= // //template <> //struct clock_time_conversion { // template // [[nodiscard]] utc_time operator()(const utc_time& timePoint) const // noexcept(is_arithmetic_v) /* strengthened */ { // return timePoint; // } //}; // //// [time.clock.cast.sys.utc] // //template <> //struct clock_time_conversion { // template // [[nodiscard]] utc_time> operator()(const sys_time& _Sys_time) const { // return utc_clock::from_sys(_Sys_time); // } //}; // //template <> //struct clock_time_conversion { // template // [[nodiscard]] sys_time> operator()(const utc_time& _Utc_time) const { // return utc_clock::to_sys(_Utc_time); // } //}; } } #endif c++-annotations-12.5.0/yo/namespaces/filesystem/examples/perms.cc0000664000175000017500000000124114624637133023704 0ustar frankfrank#include #include using namespace std; using namespace filesystem; int main() { path perm{ "perms.cc" }; auto stat = status(perm); cout << oct << "permissions: " << static_cast(stat.permissions()) << '\n'; permissions(perm, perms::owner_write, perm_options::remove); stat = status(perm); cout << oct << "permissions: " << static_cast(stat.permissions()) << '\n'; permissions(perm, perms::owner_write, perm_options::add); stat = status(perm); cout << oct << "permissions: " << static_cast(stat.permissions()) << '\n'; } c++-annotations-12.5.0/yo/namespaces/filesystem/examples/statusknown.cc0000664000175000017500000000302314624637133025156 0ustar frankfrank#include #include #include using namespace std; using namespace filesystem; //demo namespace { std::unordered_map statusMap = { { file_type::not_found, "an unknown file" }, { file_type::none, "not yet or erroneously evaluated " "file type" }, { file_type::regular, "a regular file" }, { file_type::directory, "a directory" }, { file_type::symlink, "a symbolic link" }, { file_type::block, "a block device" }, { file_type::character, "a character device" }, { file_type::fifo, "a named pipe" }, { file_type::socket, "a socket file" }, { file_type::unknown, "an unknown file type" } }; } int main() { cout << oct; string line; while (true) { cout << "enter the name of a file system entry: "; if (not getline(cin, line) or line.empty()) break; path entry{ line }; error_code ec; file_status stat = status(entry, ec); if (not status_known(stat)) { cout << "status of " << entry << " is unknown. " "Ec = " << ec << '\n'; continue; } cout << "status of " << entry << ": type = " << statusMap[stat.type()] << ", permissions: " << static_cast(stat.permissions()) << '\n'; } } //= c++-annotations-12.5.0/yo/namespaces/filesystem/examples/path.cc0000664000175000017500000000105114624637133023511 0ustar frankfrank#include #include using namespace std; using namespace filesystem; int main() { path p{ "/abs/olu/te.cc" }; p.replace_filename("this/part"); cout << "Current path is " << current_path() << '\n' << "Absolute path for " << p << " is " << absolute(p) << '\n'; cout << absolute("tmp/filename") << '\n'; p /= "extension"; cout << p << '\n'; cout << path{}.append("entry") << '\n'; cout << p.replace_extension("out") << '\n'; cout << p.replace_extension(".out") << '\n'; } c++-annotations-12.5.0/yo/namespaces/filesystem/examples/absolute.cc0000664000175000017500000000041614624637133024377 0ustar frankfrank#include #include using namespace std; using namespace filesystem; int main() { path p{ "absolute.cc" }; cout << "Current path is " << current_path() << '\n' << "Absolute path for " << p << " is " << absolute(p) << '\n'; } c++-annotations-12.5.0/yo/namespaces/filesystem/examples/breadth.cc0000664000175000017500000000217414624637133024175 0ustar frankfrank#include #include #include using namespace std; using namespace filesystem; //code void breadth(path const &dir) // starting dir. { vector level{ dir }; // currently processed level while (not level.empty()) // process all its dirs. { vector next; // dirs of the next level for (auto const &dir: level) // visit all dirs at this level { cout << "At " << dir << '\n'; // at each dir: visit all entries for (auto const &entry: directory_iterator{ dir }) { if (entry.is_directory()) // store all dirs at the current next.push_back(entry); // level else // or process its non-dir entry cout << " entry: " << entry << '\n'; } } level = next; // continue at the next level, } // which eventually won't exist } //= int main() { breadth("/home/frank/tmp"); } c++-annotations-12.5.0/yo/namespaces/filesystem/examples/lastwritetime.cc0000664000175000017500000000312414624637133025455 0ustar frankfrank#include #include #include using namespace std; using namespace filesystem; using namespace chrono; // t1; // 1'573'443'680 '202'029'390 // -4'864'220'319 '797'970'245 // // t0: // 1'573'443'602 '813'273'869 // -4'864'220'397 '186'725'741 // 6'437'663'999 //demo int main() { // get `now' according to the system_clock and // the __file_clock, compute their difference in // nanoseconds and seconds: auto systemNow = system_clock::now().time_since_epoch(); auto fileNow = __file_clock::now().time_since_epoch(); duration diffNano = systemNow - fileNow; time_t diff = diffNano.count() / 1'000'000'000; cout << "system_clock now: " << systemNow.count() << "\n" "__file_clock now: " << fileNow.count() << "\n" "difference (nano): " << diffNano.count() << "\n" "difference (secs): " << diff << '\n'; auto lwt = last_write_time("lastwritetime.cc").time_since_epoch(); time_t seconds = diff + system_clock::to_time_t( time_point{ nanoseconds(lwt) } ); cout << "lastwritetime.cc's time: " << put_time(gmtime(&seconds), "%c") << '\n'; seconds = system_clock::to_time_t(time_point{ diffNano }); cout << "__file_clock's epoch time expressed using the system_clock:\n" " " << put_time(gmtime(&seconds), "%c") << "\n" "same, merely using the difference in `now' clock-seconds:\n" " " << put_time(gmtime(&diff), "%c") << '\n'; } //= c++-annotations-12.5.0/yo/namespaces/filesystem/examples/direntry.cc0000664000175000017500000000110014624637133024410 0ustar frankfrank#include #include using namespace std; using namespace filesystem; int main() { directory_entry one; one = directory_entry{ "one" }; one = one; cout << (one == directory_entry( "one" )) << '\n'; directory_iterator("/home")->status(); cout << *directory_iterator{ "/home" } << '\n'; directory_iterator dir; filesystem::begin( directory_iterator{ "/home" } ); filesystem::end( directory_iterator{ "/home" } ); for (directory_entry const &de: directory_iterator{ "/home" }) cout << de << '\n'; } c++-annotations-12.5.0/yo/namespaces/filesystem/spaceinfo.yo0000644000175000017500000000242014466730207022747 0ustar frankfrankEvery existing tt(path) lives in a file system, Sizes of file systems typically are quite large, but there is a limit to their sizes. The size of file systems, the number of bytes that is currently being used and the remaining number of bytes is made available by the function hi(space(_info))hi(available space) tt(space(path const &entry [, error_code &ec])), returning the information about the file system containing tt(entry) in a POD tt(struct space_info). If the tt(error_code) argument is provided then it is cleared if no error occurs, and set to the operating system's error code if an error has occurred. If an error occurs and the tt(error_code) argument was not provided then a tt(filesystem_error) exception is thrown, receiving tt(path) as its first argument and the operating system's error code as its tt(error_code) argument. The returned tt(space_info) has three fields: verb( uintmax_t capacity; // total size in bytes uintmax_t free; // number of free bytes on the file system uintmax_t available; // free bytes for a non-privileged process) If a field cannot be determined it is set to -1 (i.e., the max. value of the type tt(uintmax_t)). The function can be used this way: verbinsert(-s4 //demo examples/spaceinfo.cc) c++-annotations-12.5.0/yo/namespaces/filesystem/filestatus.yo0000644000175000017500000001316314624366470023174 0ustar frankfrankFile system entries (represented by tt(path) objects), have several attributes: permissions (e.g., the owner may modifiy an entry, others may only read entries), and types (like plain files, directories, and soft-links). The following types and functions are all defined in the tt(std::filesystem) namespace which may be abbreviated to tt(fs) by using `tt(namespace fs = std::filesystem;)'. Types and permissions of file system entries are available through objects of the class ti(file_status). The class tt(file_status) is a value-class supporting copy- and move- constructors and assignment operators. The constructor verb( explicit file_status(file_type type = file_type::none, perms permissions = perms::unknown)) creates the file status for a specific type of file system entry having a specific set of permissions. It also acts as default constructor. The constructor's first parameter is an enumeration specifying the type of a file system entry represented by a tt(path) object: itemization( itt(not_found = -1) indicates that a file system entry whose status was requested was not found (this is not considered an error); itt(none) indicates either that the file status has not yet been evaluated, or that an error occurred when an entry's status was evaluated; itt(regular): the entry is a regular file; itt(directory): the entry is a directory; itt(symlink): the entry is a symbolic link; itt(block): the entry is a block device; itt(character): the entry is a character device; itt(fifo): the entry is a named pipe; itt(socket): the entry is a socket file; itt(unknown): the entry is an unknown file type ) The constructor's second parameter defines the tt(enum class perms) specifying the access permissions of file system entries. The enumeration's symbols were selected so that their meanings should be more descriptive than the constants defined in the tthi(sys/stat.h) header file, but other than that they have identical values. All bitwise operators can be used by values of the tt(enum class perms). Here is an overview of the symbols defined by the tt(enum class perms) (note that a common octal value permission specification as used in the tt(sys/stat.h) header value cannot directly be used as tt(fs::perms) value, but requires a cast like tt(static_cast(value))): centertbl(lrll)(\ tline()()\ tr(xcell(4)(Permission specifiers))\ tr(cell(Symbol)cell(Value)cell(sys/stat.h)tlc()(Meaning))\ tline()()\ rowfour(none)(0000)()(No permission bits were set) rowfour(owner_read)(0400)(S_IRUSR)(File owner has read permission) rowfour(owner_write)(0200)(S_IWUSR)(File owner has write permission) rowfour(owner_exec)(0100)(S_IXUSR)(File owner has execute/search permissions) rowfour(owner_all)(0700)(S_IRWXU)(File owner has read, write, and execute/search permissions) rowfour(group_read)(0040)(S_IRGRP)(The file's group has read permission) rowfour(group_write)(0020)(S_IWGRP)(The file's group has write permission) rowfour(group_exec)(0010)(S_IXGRP)(The file's group has execute/search permissions) rowfour(group_all)(0070)(S_IRWXG)(The file's group has read, write, and execute/search permissions) rowfour(others_read)(0004)(S_IROTH)(Other users have read permission) rowfour(others_write)(0002)(S_IWOTH)(Other users have write permission) rowfour(others_exec)(0001)(S_IXOTH)(Other users have execute/search permissions) rowfour(others_all)(0007)(S_IRWXO)(Other users have read, write, and execute/search permissions) rowfour(all)(0777)()(All users have read, write, and execute/search permissions) rowfour(set_uid)(04000)(S_ISUID)(Set user ID to file owner user ID on execution) rowfour(set_gid)(02000)(S_ISGID)(Set group ID to file's user group ID on execution) rowfour(sticky_bit)(01000)(S_ISVTX)(POSIX XSI specifies that when set on a directory+htmlcommand(
) only file owners may delete files even if the directory is writeable by others+htmlcommand(
) (used, e.g., with tt(/tmp))) rowfour(mask)(07777)()(All valid permission bits.) tline()()\ ) The class tt(file_status) provides these members: itemization( itht(permissions)(perms permissions() const) and tt(void permissions(perms newPerms [, perm_options opts] [, error_code &ec])):nl() the former member returns the permissions of the file system entry represented by the tt(file_status) object, the latter can be used to modify those permissions. The hi(perm_options)tt(enum class perm_options) has these values: itemization( itt(replace): current options are replaced by tt(newPerms); itt(add): tt(newPerms) are added to the current permissions; itt(remove): tt(newPerms) are removed from the current permissions; itt(nofollow): when tt(path) refers to a symbolic link the permissions of the symbolic link instead of those of the file system entry the link refers to are updated. ) itht(type)(file_type type() const) and tt(void type(file_type type)):nl() the former member returns the type of the file system entry represented by the tt(file_status) object, the latter can be used to set the type. ) c++-annotations-12.5.0/yo/namespaces/filesystem/filesystemerror.yo0000644000175000017500000000120614466730207024237 0ustar frankfrankThe tt(std::filesystem) namespace offers its own exception type ti(filesystem_error) (see also chapter ref(EXCEPTIONS)). Its constructor has the following signature (the bracketed parameters are optional): verb( filesystem_error(string const &what, [path const &path1, [path const &path2,]] error_code ec);) As tt(filesystem) facilities are closely related to standard system functions, tt(errc) error code enumeration values can be used to obtain tt(error_codes) to pass to tt(filesystem_error), as illustrated by the following program: verbinsert(-s4 //fse examples/filesystemerror.cc) c++-annotations-12.5.0/yo/namespaces/filesystem/errorcode.yo0000644000175000017500000001370614533052507022770 0ustar frankfrankObjects of the class ti(std::error_code) (note: em(not) tt(std::filesystem::error_code)!) encapsulate em(error values), and associated em(error categories) (cf. section ref(SYSTEMERROR); tt(error_code) can be used after including the tthi(system_error) header, but it is also available after including the tthi(filesystem) header file). Traditionally error values are available as values assigned to the global hi(errno) tt(int errno) variable. By convention, when tt(errno's) value equals zero there's no error. This convention was adopted by tt(error_code). Error codes can be defined for many conceptually different situations. Those situations are characterized by their own em(error categories). Error categories are used to associate tt(error_code) objects with the errors that are defined by those categories. Default available error categories may use values like tt(EADDRINUSE) (or the equivalent tt(enum class errc) value tt(address_in_use)) but new types of error categories, tailored to other contexts, can also be defined. Defining error categories is covered near the end of the annotations() (section ref(ERRCAT)). At this point two tt(error_category) members are briefly introduced: itemization( itt(std::string message(int err)) returning a textual description of error tt(err) (like em(address already in use) when tt(err) equals tt(address_in_use)). itt(char const *name()) returning the name of the error category (like em(generic) for the generic category); ) Error category classes are singleton classes: only one object exists of each error category. In the context of the filesystem namespace the standard category ti(system_category) is used, and a reference to the ti(system_category) object is returned by the free function tt(std::system_category), expecting no arguments. The public interface of the class tt(error_code) declares these construtors and members: bf(Constructors): itemization( ittq(error_code() noexcept) (the object is initialized with error em(value) 0 and the tt(system_category) error category. Value 0 is not considered an error;) it() Copy- and move-constructors are available; ittq(error_code(int ec, error_category const &cat) noexcept) (the object is initialized from error value tt(ec) (e.g., tt(errno), set by a failing function), and a const reference to the applicable error em(category) (provided by, e.g., hi(system_category) tt(std::system_category()) or hi(generic_category) tt(std::generic_category())). Here is an example defining an tt(error_code) object: verb( error_code ec{ 5, system_category() };)) ittq(error_code(ErrorCodeEnum value) noexcept) (this is a member template (cf. section ref(MEMTEMP)), using template header tt(template ). It initializes the object with the return value of tt(make_error_code(value)) (see below). In section ref(ERRCODEENUM) defining tt(ErrorCodeEnums) is covered. Note: tt(ErrorCodeEnum) as such does not exist. It is a mere placeholder for existing tt(ErrorCodeEnum) enumerations; ) ) bf(Members): itemization( it() The overloaded assignment operator and an assignment operator accepting an tt(ErrorCodeEnum) are available; ittq(void assign(int val, error_category const &cat)) (assigns new values to the object's error value and category. E.g, tt(ec.assign(0, generic_category()));) ittq(error_category const &category() const noexcept) (returns a reference to the object's error category;) ittq(void clear() noexcept) (sets the tt(error_code's) value to 0 and its error category to tt(system_category);) ittq(error_condition default_error_condition() const noexcept) (returns the current category's default error condition initialized with the current object's error value and error category (see section ref(ERRCOND) for details about the class tt(error_condition));) ittq(string message() const) (the message that is associated with the current object's error value is returned (equivalent to tt(category().message(ec.value())));) ittq(explicit operator bool() const noexcept) (returns true if the object's error value is unequal 0 (i.e., it represents and error)) ittq(int value() const noexcept) (returns the object's error value.) ) bf(Free functions): itemization( it() Two tt(error_code) objects can be compared for (in) equality and can be ordered (using tt(operator<)). Ordering tt(error_codes) associated with different error categories has no meaning. But when the error categories are identical then they are compared by their error code values (cf. this url(SG14 discussion summary) (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0824r1.html)); ithtq(make_error_code)(error_code make_error_code(errc value) noexcept) (returns an tt(error_code) object initialized with tt(static_cast(value)) and tt(generic_category())). This function converts an tt(enum class errc) value to an tt(error_code). Other error related enums may also be defined with which tailored tt(make_error_code) functions can be associated (cf. section ref(ERRCODEENUM);) ittq(std::ostream &operator<<(std::ostream & os, error_code const &ec)) (executes the following statement: verb(return os << ec.category().name() << ':' << ec.value();) ) ) Several functions introduced below define an optional last tt(error_code &ec) parameter. Those functions have tt(noexcept) specifications. If those functions cannot complete their tasks, then tt(ec) is set to the appropriate error code, calling tt(ec.clear()) if no error was encountered. If no tt(ec) argument is provided then those functions throw a tt(filesystem_error) exception if they cannot complete their tasks. c++-annotations-12.5.0/yo/namespaces/filesystem/directoryentry.yo0000644000175000017500000000471714466730207024101 0ustar frankfrankThe file system is a recursive data structure. Its top-level entry is a directory (the root directory) containing plain directory entries (files, (soft) links, named sockets, etc.) and possibly also (sub)directory entries referring to nested directories which in turn may contiain plain- and (sub)directory entries. In the tt(std::filesystem) namespace the elements of directories are objects of the class ti(directory_entry), containing names and statuses of the entries of that directory. The class tt(directory_entry) supports all standard constructors and assignment operators and in addition a constructor expecting a tt(path): verb( directory_entry(path const &entry);) Objects of the class tt(directory_entry) can be constructed by name, without requiring that those objects refer to existing entries in the computer's file system. The assignment operator is also available, as is the (tt(ostream)) insertion operator, inserting the object's tt(path) into the stream. The extraction operator is not available. `tt(directory_entry)' objects may be compared using the tt(==, !=, <, <=, >,) and tt(>=) operators. These operators are then applied to their tt(path) objects: tt(directory_entry("one") == directory_entry("one")) returns tt(true). In addition to these operators the class tt(directory_entry) also has these member functions: itemization( ithtq(assign)(void assign(path const &dest)) (the current path is replaced by tt(dest) (its action is identical to that of the overloaded assignment operator);) ithtq(replace_filename)(void replace_filename(path const &dest)) (the last element of the current object's path is replaced by tt(dest). If that element is empty (like when the object's path ends in a directory separator) then tt(dest) is appended to the current object's path;) itht(path)(path const &path() const), hi(operator path const &()) tt(operator path const &() const):nl() the current object's path name is returned; ithtq(status)(filesystem::file_status status([error_code &ec])) (returns type and attributes of the directory entry referred to by the current object. If the current object refers to a symlink then the status of the entry the symlink refers to is returned. To obtain the status of the entry itself, even if it's a symlink use ti(symlink_status) (see also section ref(FSSTATUS) and ref(FSESTAT) below).) ) c++-annotations-12.5.0/yo/namespaces/filesystem/fileclock.yo0000644000175000017500000000603014466730207022734 0ustar frankfrankIn section ref(CLOCKS) it was stated that various predefined clocks are available, of which the tt(system_clock) refers to the clock used by the computer itself. The tt(filesystem) namespace uses a different clock: the tt(std::filesystem::__file_clock). Time points obtained using the ti(__file_clock) differ from the time points obtained using the system clock: time points using the tt(__file_clock) are based on an epoch that (currently) lies well beyond the epoch Jan 1, 00:00:00 1970 that is used by the system clock: Fri Dec 31 23:59:59 2173. The two epochs can be positioned on a time scale with the present somewhere in between: verb( <------|-----------------------|-----------------------|-------> system_clock's --------> present <-------- __file_clock's epoch starts positive negative epoch starts count count) The tt(__file_clock) has its own peculiarities: the static member tt(now) is available, as are some non-static members: additions and subtractions of durations and the member tt(time_since_epoch) can all be used, and . The other members (tt(to_time_t, from_time_t, min) and tt(max)) aren't available. Since tt(to_time_t) is not available for tt(__file_clock) how can we show the time or obtain the time's components of a tt(time_point<__file_clock>) object? Currently, there are two ways to accomplish that: compute the correction `by hand' or use the static ti(__file_clock::to_sys) function converting a hi(time_point<__file_clock>) tt(__file_clock) time point to a tt(time_point) as used by tt(system_clock, steady_clock,) and tt(high_resolution_clock). Computing the difference between the epochs we find 6'437'663'999 seconds, which we can add to the obtained time since the tt(__file_clock's) epoch to obtain the time since the tt(system_clock's) epoch. If tt(timePt) holds the duration since the tt(__file_clock) epoch then verb( 6'437'663'999 + system_clock::to_time_t( time_point{ nanoseconds(timePt) })) equals the number of seconds since the tt(system_clock's) epoch. The potential drawback of this procedure is that, as tt(__file_clock's) name starts with underscores, the begin of its epoch might change. By using the tt(now) members of both clocks this drawback is avoided: verb( auto systemNow = system_clock::now().time_since_epoch(); auto fileNow = __file_clock::now().time_since_epoch(); time_t diff = (systemNow - fileNow) / 1'000'000'000; time_t seconds = diff + system_clock::to_time_t( time_point{ nanoseconds(timePt) });) Although being able to compute the time-shifts yourself is attractive from an understanding point of view, it's maybe also a bit (too) cumbersome for daily practices. The static function tt(__file_clock::to_sys) can be used to convert tt(__file_clock::time_points) to tt(system_clock:::time_points). The tt(__file_clock::to_sys) function is covered in section ref(FREEFS). COMMENT( see examples/lastwritetime[2].cc) c++-annotations-12.5.0/yo/namespaces/filesystem/pathmembers.yo0000644000175000017500000001374414466730207023322 0ustar frankfrank The class tt(path) provides the following operators and members: bf(Operators:) itemization( itt(path &operator/=(Type const &arg)):nl() the arguments that can be passed to the constructors can also be passed to this member. The tt(arg) argument is separated from the path's current content by a directory separator (unless the path is initially empty as in tt(cout << path{}.append("entry"))). See also the members tt(append) and tt(concat), below. The free operator tt(/) accepts two tt(path) (promotable) arguments, returning a tt(path) containing both paths separated by a directory separator (e.g., tt(lhs / rhs) returns a tt(path) object containing tt(lhs/rhs)); itt(path &operator+=(Type const &arg)):nl() similar to tt(/=), but em(no) directory separator is used when adding tt(arg) to the current tt(path); it() comparison operators: tt(path) objects can be compared using the (operators implied by the) tt(==) and tt(<=>) operators. Path objects are compared by lexicographical comparing their ascii-character content. ) bf(Accessors:) Accessors return specific tt(path) components. If a path doesn't contain the requested component then an empty tt(path) is returned. itemization( itt(char const *c_str()): the path's content as an NTBS is returned; itt(path extension()) returns the dot-extension of the path's last component (including the dot); itt(path filename()) returns the last path-content of the current tt(path) object. See also the tt(stem()) accessor, below; itt(bool is_absolute()): returns tt(true) if the tt(path) object contains an absolute path specification; itt(bool is_relative()): returns tt(true) if the tt(path) object contains a relative path specification; itt(path parent_path()) returns the current path-content from which the last element has been removed. Note that if the tt(path) object contains a filename's path (like tt("/usr/bin/zip")) then tt(parent_path) removes tt(/zip) and returns tt(/usr/bin), so not tt(zip's) parent directory, but its actual directory; itt(path relative_path()): returns the path's content beyond the path's root-directory component of the tt(path) object. E.g., if the tt(path ulb{ "/usr/local/bin" }) is defined then tt(ulb.relative_path()) returns a path containing tt("usr/local/bin"); itt(path root_directory()): returns the root-directory component of the tt(path) object; itt(path root_name()): returns the root-name's component of the tt(path) object; itt(path root_path()): returns the root-path component of the tt(path) object; itt(path stem()) returns the last path-content of the current tt(path) object from which the dot-extension hash been removed; itt(string()): returns the path's content as a tt(std::string).nl() Similar accessors are available for the following string-types: tt(wstring, u8string, u16string, , u32string, generic_string, generic_wstring, generic_u8string, generic_u16string,) and tt(generic_u32string); ) Except for the family of tt(string()) and the tt(is_...) accessors, there are also tt(bool has_...) members returning tt(true) if the tt(path) contains the specified component (e.g., tt(has_extension) returns tt(true) if the tt(path) contains an extension). bf(Member functions:) itemization( itt(path &append(Type const &arg)) acts like the tt(/=) operator; itt(path::iterator begin()) returns an iterator containing the first path component; Dereferencing a tt(path::iterator) returns a tt(path) object.nl() When available root names and root directories are returned as initial components. When incrementing tt(path::iterators) the individual directories and finally filename components are returned. The directory separators themselves are not returned when dereferencing subsequent tt(path::iterators); itt(void clear()): the tt(path's) content is erased; itt(int compare(Type const &other)):nl() returns the result of lexicographically comparing the current path's content with tt(other). tt(Other) can be a tt(path), a string-type or an NTBS; itt(path &concat(Type const &arg)) acts like the tt(+=) operator; itt(ostream &operator<<(ostream &out, path const &path)) (stream insertion) inserts tt(path's) content, surrounded by double quotes, into tt(out); itt(istream &operator>>(istream &in, path &path)) extracts tt(path's) content from tt(in). The extracted path name may optionally be surrounded by double quotes. When inserting a previously extracted tt(path) object only one set of surrounding quotes are shown. itt(path &remove_filename()):nl() removes the last component of the stored path. If only a root-directory is stored, then the root directory is removed. Note that the last directory separator is kept, unless it is the only path element; itt(path &replace_extension(path const &replacement = path{} )):nl() replaces the extension of the last component of the stored path (including the extension's dot) with tt(replacement). The extension is removed if tt(replacement) is empty. If the tt(path) calling tt(replace_extension) has no extension then tt(replacement) is added. The replacement may optionally start with a dot. The path object's extension receives only one dot; itt(path &replace_filename(path const &replacement)):nl() replaces the last component of the stored path with tt(replacement), which itself may contain multiple path elements. If only a root-directory is stored, then it is replaced by tt(replacement). The member's behavior is undefined if the current path object is empty; ) c++-annotations-12.5.0/yo/namespaces/filesystem/getstatus.yo0000644000175000017500000000557014466730207023034 0ustar frankfrank The tt(filesystem) functions tt(status) and tt(symlink_status) retrieve or change statuses of file system entries. These functions may be called with a final (optional) tt(error_code) argument which is assigned an appropriate error code if they cannot perform their tasks. If the argument is omitted the members throw exceptions if they cannot perform their tasks: itemization( ithtq(status)(file_status status(path const &dest [, error_code &ec])) (returns type and attributes of tt(dest). If tt(dest) is a symlink the status of the link's destination is returned;) ithtq(symlink_status)(file_status symlink_status(path const &dest [, error_code &ec])) (when calling tt(symlink_status(dest)) the status of tt(dest) itself is returned. Thus, if tt(dest) refers to a symlink then tt(symlink_status) does em(not) return the status of the entry tt(dest) refers to, but the status of tt(dest) itself: a symbolic link (with tt(file_status's type()) member returning tt(file_type::symlink));) ithtq(status_known)(bool status_known(file_status const &status)) (returns tt(true) if tt(status) refers to a determined status (tt(status) itself may indicate that the entity referred to by tt(status) does not exist). One way of receiving tt(false) is by passing it a default status object: tt(status_known(file_status{}));) ) Once a tt(file_status) object is obtained the file type of the entry whose status it represents can be interrogated using these functions (defined in the tt(filesystem) namespace, where tt(WHATEVER) is the requested specification): verb( bool is_WHATEVER(file_status status) bool is_WHATEVER(path const path &entry [, error_code &ec])) These functions return tt(true) if tt(status) or tt(status) matches the requested type. Here are the available functions: itemization( iti(is_block_file): the path refers to a block device; iti(is_character_file): the path refers to a character device; iti(is_directory): the path refers to a directory; iti(is_empty): the path refers to an empty file or directory; iti(is_fifo): the path refers to a named pipe; iti(is_other): the path does not refer to a directory, regular file or symlink; iti(is_regular_file): the path refers to a regular file; iti(is_socket): the path refers to a named socket; iti(is_symlink): the path refers to a symbolic link; ) Alternatively, the tt(file_status::type()) member can be used in, e.g., a tt(switch) to select an entry matching its tt(file_type) return value (see the previous section (ref(FSSTATUS)) for a description of the symbols defined by the tt(file_type) enum). Here is a little program showing how file statuses can be obtained and shown (for the em(map) see section ref(MAP)): verbinsert(-s4 //demo examples/statusknown.cc) c++-annotations-12.5.0/yo/namespaces/filesystem/freefunctions.yo0000644000175000017500000002372314466730207023663 0ustar frankfrankIn addition to the tt(path) member functions various free functions are available. Some of these copy files. Those functions accept an optional hi(copy_options) tt(std::filesystem::copy_options) argument. The tt(enum class copy_options) defines symbolic constants that can be used to fine-tune the behavior of these functions. The enumeration supports bitwise operators (the symbols' values are shown between parentheses) and defines these symbols: itemization( it() When copying files: itemization( itt(none) (0): report an error (default behavior); itt(skip_existing) (1): keep the existing file, without reporting an error; itt(overwrite_existing) (2): replace the existing file; itt(update_existing) (4): replace the existing file only if it is older than the file being copied; ) it() When copying subdirectories: itemization( itt(none) (0): skip subdirectories (default behavior); itt(recursive) (8): recursively copy subdirectories and their content; ) it() When copying symlinks: itemization( itt(none) (0): follow symlinks (default behavior); itt(copy_symlinks) (16): copy symlinks as symlinks, not as the files they point to; itt(skip_symlinks) (32): ignore symlinks; ) it() To control tt(copy's) behavior itself: itemization( itt(none) (0): copy file content (default behavior); itt(directories_only) (64): copy the directory structure, but do not copy any non-directory files; itt(create_symlinks) (128): instead of creating copies of files, create symlinks pointing to the originals (the source path must be an absolute path unless the destination path is in the current directory); itt(create_hard_links) (256): instead of creating copies of files, create hardlinks that resolve to the same files as the originals. ) ) The following functions expect tt(path) arguments: itemization( ithtq(absolute)(path absolute(path const &src, [, error_code &ec])) (a copy of tt(src) specified as an absolute path (i.e., starting at the filesystem's root (and maybe disk) name). It can be called like this: tt(absolute("tmp/filename")), returning the (absolute) current working directory to which tt(absolute's) argument is appended as a final element, separated by a directory separator. Relative path indicators (like tt(../) and tt(./)) are kept. The returned tt(path) merely is an absolute path. If relative path indicators should be removed, then use the next function;) ithtq(canonical)(path canonical(path const &src [, error_code &ec])) (returns tt(src's) canonical path. The argument tt(src) must refer to an existing directory entry. Example: verb( path man{ "/usr/local/bin/../../share/man" }; cout << canonical(man) << '\n'; // shows: "/usr/share/man")) ithtq(copy)(void copy(path const &src, path const &dest [, copy_options opts [, error_code &ec]])) (tt(src) must exist. Copies tt(src) to tt(dest) if the tt(cp) program would also succeed. If tt(src) is a directory, and tt(dest) does not exist, tt(dest) is created. Directories are recursively copied if copy options tt(recursive) or tt(none) were specified;) ithtq(copy_file)(bool copy_file(path const &src, path const &dest [, copy_options opts [, error_code &ec]])) (tt(src) must exist. Copies tt(src) to tt(dest) if the tt(cp) program would also succeed. Symbolic links are followed. The value tt(true) is returned if copying succeeded;) ithtq(copy_symlink)(void copy_symlink(path const &src, path const &dest [, error_code &ec])) (creates the symlink tt(dest) as a copy of the symlink tt(src);) ithtq(create_directories)(bool create_directories(path const &dest [, error_code &ec])) (creates each component of tt(dest), unless already existing. The value tt(true) is returned if tt(dest) was actually created. If tt(false) is returned tt(ec) contains an error-code, which is zero (tt(ec.value() == 0)) if tt(dest) already existed. See also tt(create_directory) below;) ithtq(create_directory)(bool create_directory(path const &dest [, path const &existing] [, error_code &ec])) (tt(dest's) parent directory must exist. This function creates directory tt(dest) if it does not yet exist. The value tt(true) is returned if tt(dest) was actually created. If tt(false) is returned tt(ec) contains an error-code, which is zero (tt(ec.value() == 0)) if tt(dest) already existed. If tt(existing) is specified, then tt(dest) receives the same attributes as tt(existing);) ithtq(create_directory_symlink)(void create_directory_symlink(path const &dir, path const &link [, error_code &ec])) (like tt(create_symlink) (see below), but is used to create a symbolic link to a directory;) ithtq(create_hardlink)(void create_hardlink(path const &dest, path const &link [, error_code &ec])) (creates a hard link from tt(link) to tt(dest). tt(Dest) must exist;) ithtq(create_symlink)(void create_symlink(path const &dest, path const &link [, error_code &ec])) (creates a symbolic (soft) link from tt(link) to tt(dest); tt(dest) does em(not) have to exist;) itht(current_path)(path current_path([error_code &ec])), tt(void current_path(path const &toPath [, error_code &ec])):nl() the former function returns the current working directory (cwd), the latter changes the cwd to tt(toPath). The returned path's last character is not a slash, unless called from the root-directory; ithtq(equivalent)(bool equivalent(path const &path1, path const &path2 [, error_code &ec])) (tt(true) is returned if tt(path1) and tt(path2) refer to the same file or directory, and have identical statuses. Both paths must exist;) itht(exists)(bool exists(path const &dest [, error_code &ec])), tt(exists(file_status status)):nl() tt(true) is returned if tt(dest) exists (actually: if tt(status(dest[, ec])) (see below) returns tt(true)). Note: when iterating over directories, the iterator usually provides the entries' statuses. In those cases calling tt(exists(iterator->status())) is more efficient than calling tt(exists(*iterator)). When tt(dest) is the path to a symbolic reference then tt(exists) returns whether the link's destination exists or not (see also the functions tt(status) and tt(symlink_status) in section ref(DIRENTRY)); ithtq(file_size)(std::unintmax_t file_size(path const &dest [, error_code &ec])) (returns the size in bytes of a regular file (or symlink destination);) ithtq(hard_link_count)(std::uintmax_t hard_link_count(path const &dest [, error_code &ec])) (returns the number of hard links associated with tt(dest);) itht(last_write_time)(time_point<__file_clock> last_write_time(path const &dest [, error_code &ec])), tt(void last_write_time(path const &dest, time_point<__file_clock> newTime [, error_code &ec])):nl() the former function returns tt(dest's) last modification time; the latter function changes tt(dest's) last modification time to tt(newTime). tt(last_write_time's) return type is defined through a tt(using) alias for tt(chrono::time_point) (cf. section ref(TIMEPOINT)). The returned tt(time_point) is guaranteed to cover all file time values that may be encountered in the current file system. The function tt(__file_clock::to_sys) (see below) can be used to convert tt(__file_clock) time points to tt(system_clock) time_points; ithtq(read_symlink)(path read_symlink(path const &src [, error_code &ec])) (tt(src) must refer to a symbolic link or an error is generated. The link's target is returned;) itht(remove)(bool remove(path const &dest [, error_code &ec])), hi(remove_all) tt(std::uintmax_t remove_all(path const &dest [, error_code &ec])):nl() tt(remove) removes the file, symlink, or empty directory tt(dest), returning tt(true) if tt(dest) could be removed; tt(remove_all) removes tt(dest) if it's a file (or symlink); and recursively removes directory tt(dest), returning the number of removed entries; ithtq(rename)(void rename(path const &src, path const &dest [, error_code &ec])) (renames tt(src) to tt(dest), as if using the standard bf(mv)(1) command (if tt(dest) exists it is overwritten);) ithtq(resize_file)(void resize_file(path const &src, std::uintmax_t size [, error_code &ec])) (tt(src's) size is changed to tt(size) as if using the standard bf(truncate)(1) command;) ithtq(space)(space_info space(path const &src [, error_code &ec])) (returns information about the file system in which tt(src) is located;) ithtq(system_complete)(path system_complete(path const &src[, error_code& ec])) (returns the absolute path matching tt(src), using tt(current_path) as its base;) ithtq(temp_directory_path)(path temp_directory_path([error_code& ec])) ( returns the path to a directory that can be used for temporary files. The directory is not created, but its name is commonly available from the environment variables ti(TMPDIR), tt(TMP, TEMP), or tt(TEMPDIR). Otherwise, tt(/tmp) is returned.) ithtq(to_sys)(time_point __file_clock::to_sys(time_point<__file_clock> timePoint)) (here is how the time returned by tt(last_write_time) can be represented using the tt(system_clock's) epoch: verbinsert(//demo examples/lastwritetime2.cc)) ) c++-annotations-12.5.0/yo/namespaces/filesystem/directoryiterator.yo0000644000175000017500000001440614466730207024565 0ustar frankfrankThe tt(filesystem) namespace has two classes simplifying directory processing: objects of the class tt(directory_iterator) are (input) iterators iterating over the entries of directories; and objects of the class tt(recursive_directory_iterator) are (input) iterators recursively visiting all entries of directories. The classes tt((recursive_)directory_iterator) provides default, copy, and move constructors. Objects of both classes may also be constructed from a tt(path) and an optional tt(error_code). E.g., verb( directory_iterator(path const &dest [, error_code &ec]);) All members of standard input iterators (cf. section ref(ITERATORS)) are supported. These iterators point to tt(directory_entry) objects referring to entries in the computer's file system. E.g., verb( cout << *directory_iterator{ "/home" } << '\n'; // shows the first // entry under /home) End-iterators matching these objects are available through the default constructed objects of the two classes. In addition, range-based for loops can be used as shown by the next example: verb( for (auto &entry: directory_iterator("/var/log")) cout << entry << '\n';) For-statements explicitly defining iterators can also be used: verb( for ( auto iter = directory_iterator("/var/log"), end = directory_iterator{}; iter != end; ++iter ) cout << entry << '\n';) After constructing a tt((recursive_)directory_iterator base{"/var/log"}) object it refers to the first element of its directory. Such iterators can also explicitly be defined: tt(auto &iter = begin(base), auto iter = begin(base), auto &iter = base) or tt(auto iter = base). All these tt(iter) objects refer to tt(base's) data, and incrementing them also advances tt(base) to its next element: verb( recursive_directory_iterator base{ "/var/log/" }; auto iter = base; // final two elements show identical paths, // different from the first element. cout << *iter << ' ' << *++iter << ' ' << *base << '\n';) The functions tt(begin) and tt(end) that are used in the above examples are, like tt((recursive_)directory_iterator), available in the tt(filesystem) namespace. The tt(recursive_directory_iterator) also accepts a tt(directory_options) argument (see below), by default specified as tt(directory_options::none): verb( recursive_directory_iterator(path const &dest, directory_options options [, error_code &ec]);) The tt(enum class directory_options)hi(directory_options) defines values that are used to fine-tune the behavior of tt(recursive_directory_iterator) objects, supporting bitwise operators (the values of its symbols are shown between parentheses): itemization( itt(none) (0): directory symlinks are skipped, denied permission to enter a subdirectory generates an error; itt(follow_directory_symlink) (1): symlinks to subdirectories are followed; itt(skip_permission_denied) (2): directories that cannot be entered are silently skipped. ) The class tt(recursive_directory_iterator) also has these members: itemization( ithtq(depth)(int depth() const) (returns the current iteration depth. The depth of the initial directory, specified at construction-time, equals 0;) ithtq(disable_recursion_pending)(void disable_recursion_pending()) (when called before incrementing the iterator the next directory entry is not recursively visited if it is a sub-directory. Then, after incrementing the iterator recursion is again allowed. If a recursion should end at a specific depth then this function must repeatedly be called before calling the iterator's increment operator once tt(depth()) returns that specific depth;) ithtq(increment)(recursive_directory_iterator &increment(error_code &ec)) (acts identically to the iterator's increment operator. However, when an error occurs tt(operator++) throws a tt(filesystem_error) exception, while tt(increment) assigns the error to tt(ec);) ithtq(options)(directory_options options() const) (returns the option(s) specified at construction-time;) ithtq(pop)(void pop()) (ends processing the current directory, and continues at the next entry in the current directory's parent. When (in a for-statement, see the example below) called from the initial directory that directory's processing ends;) ithtq(recursion_pending)(bool recursion_pending() const) (tt(true) is returned if recursive processing of sub-directories of the currently processed directory is allowed. If so, and the directory entry the iterator points at is a sub-directory then processing continues at that sub-directory at the iterator's next increment;) ) Here is a little program displaying all directory elements of a directory and of all its immediate sub-directories. verb( int main() { recursive_directory_iterator base{ "/var/log" }; for (auto entry = base, endIt = end(base); entry != endIt; ++entry) { cout << entry.depth() << ": " << *entry << '\n'; if (entry.depth() == 1) entry.disable_recursion_pending(); } }) The above program handles entries as they come. If other strategies are needed they have to be implemented. E.g., a breadth-first strategy first visits all the non-directory entries and then visits the sub-directories. In the next example this is realized by processing each of the directories stored in tt(level) (initially it merely contains the starting directory). `Processing a directory' means that its non-directory entries are directly processed while the names of its sub-directories are stored in tt(next). Once all entries in tt(level) have been processed the names of the next level sub-directories are available in tt(next) and by assigning tt(next) to tt(level) all directories at the next level are processed. When reaching the most deeply nested sub-directories tt(next) remains empty and the tt(while) statement ends: verbinsert(-s4 //code examples/breadth.cc) c++-annotations-12.5.0/yo/namespaces/filesystem/intro.yo0000644000175000017500000000342114466730207022135 0ustar frankfrankComputers commonly store information that must survive reboots in their file systems. Traditionally, to manipulate the file system the bf(C) programming language offers functions performing the required system calls. Such functions (like bf(rename)(2), tt(truncate)(2), bf(opendir)(2), and bf(realpath)(3)) are of course also available in bf(C++), but their signatures and way of use are often less attractive as they usually expect tt(char const *) parameters and may use static buffers or memory allocation based on bf(malloc)(3) and bf(free)(3). Since 2003 the hi(Boost Filesystem)url(Boost library) (http://www.boost.org/doc/libs/1_65_1/libs/filesystem/doc/index.htm) offers em(wrappers) around these functions, offering interfaces to those system calls that are more bf(C++)-like. Currently bf(C++) directly supports these functions in the tt(std::filesystem)hi(filesystem) namespace. These facilities can be used after including the tthi(filesystem) header file. The tt(filesystem) namespace is extensive: it contains more than 10 different classes, and more than 30 free functions. To refer to the identifiers defined in the tt(std::filesystem) namespace their fully qualified names (e.g., tt(std::filesystem::path)) can be used. Alternatively, after specifying `tt(using namespace std::filesystem;)' the identifiers can be used without further qualifications. Namespace specifications like `tt(namespace fs = std::filesystem;)' are also encountered, allowing specifications like tt(fs::path). Functions in the tt(filesystem) namespace may fail. When functions cannot perform their assigned tasks they may throw exceptions (cf. chapter ref(EXCEPTIONS)) or they may assign values to tt(error_code) objects that are passed as arguments to those functions (see section ref(ERRORCODE) below). c++-annotations-12.5.0/yo/namespaces/filesystem/path.yo0000644000175000017500000000375714466730207021752 0ustar frankfrankObjects of the class tt(filesysten::path)hi(path) hold names of file system entries. The class tt(path) is a value class: a default constructor (empty path) as well as standard copy/move construction/assignment facilities are available. In addition, the following constructors can be used: itemization( itt(path(string &&tmp)); itt(path(Type const &source)):nl() any acceptable type that provides the characters of the path (e.g., tt(source) is a NTBS); itt(path(InputIter begin, InputIter end)):nl() the characters from tt(begin) to tt(end) define the tt(path's) name. ) A thus constructed tt(path) doesn't have to refer to an existing file system entry. Path constructors expect character sequences (including NTBSs) that may consist of various (all optional) elements: itemization( it() a root-name, e.g., a disk-name (like tt(E:)) or device indicator (like tt(//nfs)); it() a root-directory, present if it is the first character after the (optional) root-name; it() filename characters (not containing directory separators). In addition the `single dot filename' (tt(.)) represents the current directory and the `double dot filename' (tt(..)) represents the current directory's parent directory; it() directory separators (by default the forward slash). Multiple consecutive separators are automatically merged into one separator. ) The constructors also define a last tt(format ftmp = auto_format) parameter, for which in practice almost never an argument has to be provided (for its details see url(cppreference) (http://en.cppreference.com/w/cpp/experimental/fs/path).) Many functions expect tt(path) arguments which can usually be created from NTBSs or tt(std::string) objects as tt(path) allows promotions (cf. section ref(EXPLICIT)). E.g., the filesystem function tt(absolute) expects a tt(const &path) argument. It can be called like this: tt(absolute("tmp/filename")). c++-annotations-12.5.0/yo/namespaces/defining.yo0000644000175000017500000000253714466730207020410 0ustar frankfrankNamespaces are defined according to the following syntax: verb( namespace identifier { // declared or defined entities // (declarative region) }) The identifier used when defining a namespace is a standard bf(C++) identifier. Within the emi(declarative region), introduced in the above code example, functions, variables, structs, classes and even (nested) namespaces can be defined or declared. Namespaces cannot be defined within a function body. However, it is possible to define a namespace using multiple em(namespace) declarations. Namespaces are `em(open)' meaning that a namespace tt(CppAnnotations) could be defined in a file tt(file1.cc) and also in a file tt(file2.cc). Entities defined in the tt(CppAnnotations) namespace of files tt(file1.cc) and tt(file2.cc) are then united in one tt(CppAnnotations) namespace region. For example: verb( // in file1.cc namespace CppAnnotations { double cos(double argInDegrees) { ... } } // in file2.cc namespace CppAnnotations { double sin(double argInDegrees) { ... } }) Both tt(sin) and tt(cos) are now defined in the same tt(CppAnnotations) namespace. Namespace entities can be defined outside of their namespaces. This topic is discussed in section ref(OUTSIDE). c++-annotations-12.5.0/yo/namespaces/placeholders.yo0000644000175000017500000000217314466730207021266 0ustar frankfrankThis section contains quite a few forward references. It merely introduces the emi(placeholders) namespace, which is nested under the tt(std) namespace; this section can be skipped without loss of continuity. Before using the namespace tt(std::placeholders) the tthi(functional) header file must be included. Further down the annotations() we will encounter em(function objects) (section ref(FUNOBJ)), which are `objects' that can be used as functions. Such function objects (also called em(functors)) are extensively used in the em(Standard Template Library) (STL, chapter ref(STL)). The STL offers a function (tt(bind), see section ref(BIND)), returning a function adapter in which a function is called which may or may not already have received its arguments. If not, then em(placeholders) for arguments must be used, for which actual arguments must be specified once the functor that is returned by tt(bind) is called. Such placeholders have predefined names: tt(_1, _2, _3,) etc. These placeholders are defined in the tt(std::placeholders) namespace. Several illustrations of the use of these placeholders are found in section ref(BIND). c++-annotations-12.5.0/yo/namespaces/declaring.yo0000644000175000017500000000070114466730207020544 0ustar frankfrank Instead of em(defining) entities in a namespace, entities may also be em(declared) in a namespace. This allows us to put all the hi(namespace declarations) declarations in a header file that can thereupon be included in sources using the entities defined in the namespace. Such a header file could contain, e.g., verb( namespace CppAnnotations { double cos(double degrees); double sin(double degrees); }) c++-annotations-12.5.0/yo/namespaces/nesting.yo0000644000175000017500000000761514466730207020276 0ustar frankfrankNamespaces can be nested. Here is an example: verb( namespace CppAnnotations { int value; namespace Virtual { void *pointer; } }) The variable tt(value) is defined in the tt(CppAnnotations) namespace. Within the tt(CppAnnotations) namespace another namespace (tt(Virtual)) is nested. Within that latter namespace the variable tt(pointer) is defined. To refer to these variable the following options are available: itemization( it() The hi(fully qualified name)em(fully qualified names) can be used. A fully qualified name of an entity is a list of all the namespaces that are encountered until reaching the definition of the entity. The namespaces and entity are glued together by the scope resolution operator: verb(int main() { CppAnnotations::value = 0; CppAnnotations::Virtual::pointer = 0; }) it() A tt(using namespace CppAnnotations) directive can be provided. Now tt(value) can be used without any prefix, but tt(pointer) must be used with the tt(Virtual::) prefix: verb(using namespace CppAnnotations; int main() { value = 0; Virtual::pointer = 0; }) it() A tt(using namespace) directive for the full namespace chain can be used. Now tt(value) needs its tt(CppAnnotations) prefix again, but tt(pointer) doesn't require a prefix anymore: verb(using namespace CppAnnotations::Virtual; int main() { CppAnnotations::value = 0; pointer = 0; }) it() When using two separate tt(using namespace) directives none of the namespace prefixes are required anymore: verb(using namespace CppAnnotations; using namespace Virtual; int main() { value = 0; pointer = 0; }) it() The same can be accomplished (i.e., no namespace prefixes) for specific variables by providing specific tt(using) declarations: verb(using CppAnnotations::value; using CppAnnotations::Virtual::pointer; int main() { value = 0; pointer = 0; }) it() A combination of tt(using namespace) directives and tt(using) declarations can also be used. E.g., a tt(using namespace) directive can be used for the tt(CppAnnotations::Virtual) namespace, and a tt(using) declaration can be used for the tt(CppAnnotations::value) variable: verb(using namespace CppAnnotations::Virtual; using CppAnnotations::value; int main() { value = 0; pointer = 0; }) ) Following a tt(using namespace) directive all entities of that namespace can be used without any further prefix. If a single tt(using namespace) directive is used to refer to a nested namespace, then all entities of that nested namespace can be used without any further prefix. However, the entities defined in the more shallow namespace(s) still need the shallow namespace's name(s). Only after providing specific tt(using namespace) directives or tt(using) declarations namespace qualifications can be omitted. When fully qualified names are preferred but a long name like verb( CppAnnotations::Virtual::pointer) is considered too long, a emi(namespace alias) may be used: verb( namespace CV = CppAnnotations::Virtual;) This defines tt(CV) as an em(alias) for the full name. The variable tt(pointer) may now be accessed using: verb( CV::pointer = 0;) A namespace alias can also be used in a tt(using namespace) directive or tt(using) declaration: verb( namespace CV = CppAnnotations::Virtual; using namespace CV;) bf(Nested namespace definitions) Starting with the C++17 standard, when nesting namespaces a nested namespace can directly be referred to using scope resolution operators. E.g., verb( namespace Outer::Middle::Inner { // entities defined/declared here are defined/declared in the Inner // namespace, which is defined in the Middle namespace, which is // defined in the Outer namespace }) c++-annotations-12.5.0/yo/namespaces/referring.yo0000644000175000017500000000407314466730207020605 0ustar frankfrankGiven a namespace and its entities, the i(scope resolution operator) can be used to refer to its entities. For example, the function tt(cos()) defined in the tt(CppAnnotations) namespace may be used as follows: verb( // assume CppAnnotations namespace is declared in the // following header file: #include int main() { cout << "The cosine of 60 degrees is: " << CppAnnotations::cos(60) << '\n'; }) This is a rather cumbersome way to refer to the tt(cos()) function in the tt(CppAnnotations) namespace, especially so if the function is frequently used. In cases like these an em(abbreviated) form can be used after specifying a emi(using declaration). Following verb( using CppAnnotations::cos; // note: no function prototype, // just the name of the entity // is required.) calling tt(cos) results in a call of the tt(cos) function defined in the tt(CppAnnotations) namespace. This implies that the standard tt(cos) function, accepting radians, is not automatically called anymore. To call that latter tt(cos) function the plain scope resolution operator should be used: verb( int main() { using CppAnnotations::cos; ... cout << cos(60) // calls CppAnnotations::cos() << ::cos(1.5) // call the standard cos() function << '\n'; }) A tt(using) declaration can have restricted scope. It can be used inside a block. The tt(using) declaration prevents the definition of entities having the same name as the one used in the tt(using) declaration. It is not possible to specify a tt(using) declaration for a variable tt(value) in some namespace, and to define (or declare) an identically named object in a block also containing a tt(using) declaration. Example: verb( int main() { using CppAnnotations::value; ... cout << value << '\n'; // uses CppAnnotations::value int value; // error: value already declared. }) c++-annotations-12.5.0/yo/namespaces/std.yo0000644000175000017500000000366714466730207017424 0ustar frankfrankThe tt(std) namespace is reserved by bf(C++). The standard defines many entities that are part of the runtime available software (e.g., tt(cout, cin, cerr)); the templates defined in the em(Standard Template Library) (cf. chapter ref(STL)); and the em(Generic Algorithms) (cf. chapter ref(GENERIC)) are defined in the tt(std) namespace. Regarding the discussion in the previous section, tt(using) declarations may be used when referring to entities in the tt(std) namespace. For example, to use the tt(std::cout) stream, the code may declare this object as follows: verb( #include using std::cout;) Often, however, the identifiers defined in the tt(std) namespace can all be accepted without much thought. Because of that, one frequently encounters a tt(using) directive, allowing the programmer to omit a namespace prefix when referring to any of the entities defined in the namespace specified with the tt(using) directive. Instead of specifying tt(using) declarations the following tt(using) directive is frequently encountered: construction like verb( #include using namespace std;) Should a tt(using) directive, rather than tt(using) declarations be used? As a i(rule of thumb) one might decide to stick to tt(using) declarations, up to the point where the list becomes impractically long, at which point a tt(using) directive could be considered. Two hi(using: restrictions) restrictions apply to tt(using) directives and declarations: itemization( it() Programmers should not declare or define anything inside the tt(namespace std). This is em(not) compiler enforced but is imposed upon user code by the standard; it() tt(Using) declarations and directives should not be imposed upon code written by third parties. In practice this means that tt(using) directives and declarations should be banned from header files and should only be used in source files (cf. section ref(NAMESPACEHDR)). ) c++-annotations-12.5.0/yo/namespaces/intro.yo0000644000175000017500000000200014466730207017741 0ustar frankfrankImagine a math teacher who wants to develop an interactive math program. For this program functions like tt(cos, sin, tan) etc. are to be used accepting arguments in degrees rather than arguments in radians. Unfortunately, the function name tt(cos) is already in use, and that function accepts radians as its arguments, rather than degrees. Problems like these are usually solved by defining another name, e.g., the function name tt(cosDegrees) is defined. bf(C++) offers an alternative solution through hi(namespace)em(namespaces). Namespaces can be considered as areas or regions in the code in which identifiers may be defined. Identifiers defined in a namespace normally won't conflict with names already defined elsewhere (i.e., outside of their namespaces). So, a function tt(cos) (expecting angles in degrees) could be defined in a namespace tt(Degrees). When calling tt(cos) from within tt(Degrees) you would call the tt(cos) function expecting degrees, rather than the standard tt(cos) function expecting radians. c++-annotations-12.5.0/yo/namespaces/koenig.yo0000644000175000017500000000756014466730207020102 0ustar frankfrankIf emi(Koenig lookup) were called the `Koenig principle', it could have been the title of a new i(Ludlum) novel. However, it is not. Instead it refers to a bf(C++) technicality. `Koenig lookup' refers to the fact that if a function is called without specifying its namespace, then the namespaces of its argument types are used to determine the function's namespace. If the namespace in which the argument types are defined contains such a function, then that function is used. This procedure is called the `Koenig lookup'. As an illustration consider the next example. The function tt(FBB::fun(FBB::Value v)) is defined in the tt(FBB) namespace. It can be called without explicitly mentioning its namespace: verbinclude(-a examples/koenig1.cc) The compiler is rather smart when handling namespaces. If tt(Value) in the tt(namespace FBB) would have been defined as tt(using Value = int) then tt(FBB::Value) would be recognized as tt(int), thus causing the Koenig lookup to fail. As another example, consider the next program. Here two namespaces are involved, each defining their own tt(fun) function. There is no ambiguity, since the argument defines the namespace and tt(FBB::fun) is called: verbinclude(-a examples/koenig2.cc) Here is an example in which there em(is) an ambiguity: tt(fun) has two arguments, one from each namespace. The ambiguity must be resolved by the programmer: verbinclude(-a examples/koenig3.cc) An interesting subtlety with namespaces is that definitions in one namespace may break the code defined in another namespace. It shows that namespaces may affect each other and that namespaces may backfire if we're not aware of their peculiarities. Consider the following example: verbinclude(-a examples/koenig4.cc) Whatever happens, the programmer'd better not use any of the functions defined in the tt(ES) namespace, since that would result in infinite recursion. However, that's not the point. The point is that the programmer won't even be given the opportunity to call tt(ES::fun) since the compilation fails. Compilation fails for tt(gun) but not for tt(fun). But why is that so? Why is tt(ES::fun) flawlessly compiling while tt(ES::gun) isn't? In tt(ES::fun) tt(fun(x)) is called. As tt(x)'s type is not defined in a namespace the Koenig lookup does not apply and tt(fun) calls itself with infinite recursion. With tt(ES::gun) the argument is defined in the tt(FBB) namespace. Consequently, the tt(FBB::gun) function is a possible candidate to be called. But tt(ES::gun) itself also is possible as tt(ES::gun)'s prototype perfectly matches the call tt(gun(x)). Now consider the situation where tt(FBB::gun) has not yet been declared. Then there is of course no ambiguity. The programmer responsible for the tt(ES) namespace is resting happily. Some time after that the programmer who's maintaining the tt(FBB) namespace decides it may be nice to add a function tt(gun(Value x)) to the tt(FBB) namespace. Now suddenly the code in the namespace tt(ES) breaks because of an addition in a completely other namespace (tt(FBB)). Namespaces clearly are not completely independent of each other and we should be aware of subtleties like the above. Later in the annotations() (chapter ref(OVERLOADING)) we'll return to this issue. em(Koenig lookup) is only used in the context of namespaces. If a function is defined outside of a namespace, defining a parameter of a type that's defined inside a namespace, and that namespace also defines a function with an identical signature, then the compiler reports an ambiguity when that function is called. Here is an example, assuming the abovementioned namespace tt(FBB) is also available: verb( void gun(FBB::Value x); int main(int argc, char **argv) { gun(FBB::Value{}); // ambiguity: FBB::gun and ::gun can both // be called. }) c++-annotations-12.5.0/yo/namespaces/chrono/0000755000175000017500000000000014562372361017535 5ustar frankfrankc++-annotations-12.5.0/yo/namespaces/chrono/examples/0000755000175000017500000000000014624637126021355 5ustar frankfrankc++-annotations-12.5.0/yo/namespaces/chrono/examples/timepoint.cc0000664000175000017500000000151714624637133023700 0ustar frankfrank#include #include #include using namespace std; using namespace chrono; using namespace filesystem; int main() { time_point tp; time_point tp2; tp2 += seconds(5); // to_time_t(tp); time_point minpoint = time_point::min(); cout << minpoint.time_since_epoch().count() << '\n'; cout << time_point::min().time_since_epoch().count() << '\n'; // time_point tp3{ tp2 }; time_point tp3{ time_point{} += seconds{ 5 } }; cout << tp3.time_since_epoch().count() << '\n'; // time_point{} + 1s }; } c++-annotations-12.5.0/yo/namespaces/chrono/examples/clock.cc0000664000175000017500000000242214624637133022757 0ustar frankfrank #include #include #include using namespace std; using namespace chrono; using namespace filesystem; auto local_time_point(time_point const &tp, char const *fmt) { time_t secs = system_clock::to_time_t( tp ); return put_time(localtime(&secs), fmt); } int main() { // system_clock::duration ds{ 24h }; // __file_clock::duration df{ 1h }; system_clock::from_time_t( system_clock::to_time_t( system_clock::from_time_t( 12345 ) ) ); std::time_t tm {time(0)}; std::cout << std::put_time(std::localtime(&tm), "%c") << '\n'; time_t secs = system_clock::to_time_t( system_clock::now() ); cout << put_time(std::localtime(&secs), "%c\n"); cout << local_time_point(system_clock{}.now(), "%c") << '\n'; // __file_clock::to_time_t(__file_clock::from_time_t(12345)); high_resolution_clock::to_time_t(high_resolution_clock::from_time_t(12345)); // steady_clock::to_time_t(steady_clock::from_time_t(12345)); // unsigned uval = system_clock::period::num; // __file_clock::period rf; // system_clock::rep vs; // __file_clock::rep vf; // system_clock::time_point st = system_clock{}.now(); __file_clock::time_point ft; } c++-annotations-12.5.0/yo/namespaces/chrono/examples/milli.cc0000664000175000017500000000030114624637133022764 0ustar frankfrank#include #include using namespace std; int main() { //milli cout << milli::num << ',' << milli::den << '\n' << kilo::num << ',' << kilo::den << '\n'; //= } c++-annotations-12.5.0/yo/namespaces/chrono/examples/durationmembers.cc0000664000175000017500000000146014624637133025065 0ustar frankfrank#include #include using namespace std; using namespace chrono; int main() { milliseconds amount(30); amount = seconds{5}; minutes halfHour{ 30 }; hours oneHour{ 1 }; cout << (halfHour + oneHour).count() << '\n'; // displays 90 halfHour += oneHour; // halfHour.count() == 90 // oneHour += halfHour; // won't compile minutes min{ 1h }; cout << min.count() << '\n'; minutes fullHour = minutes{ 30 } + halfHour; halfHour = 2 * fullHour; halfHour = fullHour / 2; fullHour = halfHour + halfHour; halfHour /= 2; halfHour *= 2; cout << halfHour.count() << ' ' << fullHour.count() << '\n'; cout << seconds::zero().count() << '\n'; cout << minutes::min().count() << ' ' << minutes::max().count() << '\n'; } c++-annotations-12.5.0/yo/namespaces/chrono/examples/ratio.cc0000664000175000017500000000031014624637133022774 0ustar frankfrank#include #include using namespace std; int main() { cout << ratio<5, 1000>::num << ',' << ratio<5, 1000>::den << '\n' << milli::num << ',' << milli::den << '\n'; } c++-annotations-12.5.0/yo/namespaces/chrono/timepoint.yo0000644000175000017500000001205214466730207022116 0ustar frankfrankSingle moments in time can be specified through objects of the class hi(time_point)tt(std::chrono::time_point). Before using the class tt(time_point) the tthi(chrono) header file must be included. Like tt(duration) the class tt(time_point) requires two template arguments: A clock type and a duration type. Usually tt(system_clock) is used as the clock's type using tt(nanoseconds) as the default duration type (it may be omitted if tt(nanoseconds) is the intended duration type). Otherwise specify the duration type as the tt(time_point's) second template argument. The following two time point definitions therefore use identifcal time point types: verb( time_point tp1; time_point tp2;) The class tt(time_point) supports three constructors: itemization( itt(time_point()):nl() the default constructor is initialized to the beginning of the clock's emi(epoch). For tt(system_clock) it is January, 1, 1970, 00:00h, but notice that tt(filesystem::__file_clock) uses a different epoch (see section ref(FILECLOCK) below); itt(time_point(time_point const &other)):nl() the copy constructor (cf. chapter ref(MEMORY)) initializes a tt(time_point) object using the time point defined by tt(other). If tt(other's) resolution uses a larger period than the period of the constructed object then tt(other's) point in time is represented in the constructed object's resolution (an illustration is provided below, at the description of the member tt(time_since_epoch)); itt(time_point(time_point const &&tmp)):nl() the move constructor (cf. chapter ref(MEMORY)) acts comparably to the copy constructor, converting tt(tmp's) resolution to the constructed object while moving tt(tmp) to the constructed object. ) The following operators and members are available: itemization( itt(time_point &operator+=(duration const &amount)):nl() The amount of time represented by tt(amount) is added to the current tt(time_point) object. This operator is also available as binary arithmetic operator using a tt(time_point const &) and a tt(duration const &) operand (in any order). Example: verb( system_clock::now() + seconds{ 5 };) itt(time_point &operator-=(duration const &amount)):nl() The amount of time represented by tt(amount) is subtracted from the current tt(time_point) object. This operator is also available as binary arithmetic operator using a tt(time_point const &) and a tt(duration const &) operand (in any order). Example: verb( time_point point = system_clock::now(); point -= seconds{ 5 };) itht(time_since_epoch)(duration time_since_epoch() const):nl() tt(duration) is the duration type used by the time point object for which this member is called. It returns the amount of time since the epoch that's represented by the object. itt(time_point min() const):nl() a static member returning the time point's tt(duration::min) value. Example: verb( cout << time_point::min().time_since_epoch().count() << '\n'; // shows -9223372036854775808) itt(time_point max() const):nl() a static member returning the time point's tt(duration::max) value. ) All predefined clocks use nanoseconds as their time resolution. To express the time in a less precise resolution take one unit of time of the less precise resolution (e.g., tt(hours(1))) and convert it to nanoseconds. Then divide the value returned by the time point's tt(time_since_epoch().count()) member by tt(count) member of the less precise resolution converted to nanoseconds. Using this procedure the number of hours passed since the beginning of the epoch can be determined: verb( cout << system_clock::now().time_since_epoch().count() / nanoseconds(hours(1)).count() << " hours since the epoch\n";) Time point objects based on the system clock or on the high resolution clock can be converted to tt(std::time_t) (or the equivalent type tt(time_t)) values. Such tt(time_t) values are used when converting time to text. For such conversions the em(manipulator) tt(put_time) (cf. section ref(IOFORMAT)) is commonly used, but tt(put_time) must be provided with the address of a tt(std::tm) object, which in turn can be obtained from a tt(std::time_t) value. The whole process is fairly complex, and the core elements are visualized in figure ref(TIMEIMG). figure(threading/time)(Time according to bf(C++))(TIMEIMG) The essential step eventually leading to the insertion of a time point's value into a tt(std::ostream) consists of using tt(system_clock::to_time_t(time_point const &tp)) to convert a time point to a tt(time_t) value (instead of using tt(system_clock) the tt(high_resolution_clock) can also be used). How a time point can be inserted into a tt(std::ostream) is described in section ref(PUTTIME). c++-annotations-12.5.0/yo/namespaces/chrono/clock.yo0000644000175000017500000000633114562372361021204 0ustar frankfrankClocks are used for measuring time. bf(C++) offers several predefined emi(clock) types, and all but one of them are defined in the tt(std::chrono) namespace. The exception is the clock tt(std::filesystem::__file_clock) (see section ref(FILECLOCK) for its details). Before using the tt(chrono) clocks the tthi(chrono) header file must be included. We need clock types when defining points in time (see the next section). All predefined clock types define the following types: itemization( it() the clock's duration type: tt(Clock::duration) (predefined clock types use tt(nanoseconds)). E.g., tt(system_clock::duration oneDay{ 24h }); it() the clock's resolution type: tt(Clock::period) (predefined clock types use tt(nano)). E.g., tt(cout << system_clock::period::den << '\n'); it() the clock's type that is used to store amounts of time: tt(Clock::rep) (predefined clock types use tt(int64_t)). E.g., tt(system_clock::rep amount = 0); it() the clock's type that is used to store time points (described in the next section): tt(Clock::time_point) (predefined clock types use tt(time_point)) E.g., tt(system_clock::time_point start). ) All clock types have a member ti(now) returning the clock type's tt(time_point) corresponding to the current time (relative to the clock's epoch). It is a static member and can be used this way: tt(system_clock::time_point tp = system_clock::now()). There are three predefined clock types in the chrono namespace: itemization( iti(system_clock) is the `wall clock', using the system's real time clock; iti(steady_clock) is a clock whose time increases in parallel with the increase of real time; iti(high_resolution_clock) is the computer's fastest clock (i.e., the clock having the shortest timer-tick interval). In practice this is the same clock as tt(system_clock). ) hi(to_sys (__file_clock)) In addition, the tt(__file_clock) clock type is defined in the tt(std::filesystem) namespace. The epoch time point of tt(__file_clock) differs from the epoch time used by the other clock types, but tt(__file_clock) has a static member tt(to_sys(__file_clock::time_point)) converting tt(__file_clock::time_points) to tt(system_clock::time_points) (tt(__file_clock) is covered in more detail in section ref(FILECLOCK)). In addition to tt(now) the classes tt(system_clock) and tt(high_resolution_clock) (referred to as tt(Clock) below) offer these two static members: itemization( itht(to_time_t) (std::time_t Clock::to_time_t(Clock::time_point const &tp))nl() a tt(std::time_t)hi(time_t) value (the same type as returned by bf(C)'s bf(time)(2) function) representing the same point in time as tt(timePoint). itht(from_time_t)(Clock::time_point Clock::from_time_t(std::time_t seconds))nl() a tt(time_point) representing the same point in time as tt(time_t). ) The example illustrates how these functions can be called: verb( system_clock::from_time_t( system_clock::to_time_t( system_clock::from_time_t( time(0); ) ) );) c++-annotations-12.5.0/yo/namespaces/chrono/ratio.yo0000644000175000017500000000563114466730207021231 0ustar frankfrankTime resolutions (or em(units of time)) are essential components of time specifications. Time resolutions are defined through objects of the class hi(ratio)tt(std::ratio). Before the class tt(ratio) can be used, the tthi(ratio) header file must be included. Instead the tt() header file can be included. The class tt(ratio) requires two em(template arguments). These are positive integral numbers surrounded by pointed brackets defining, respectively, the numerator and denominator of a fraction (by default the denominator equals 1). Examples: verb( ratio<1> - representing one; ratio<60> - representing 60 ratio<1, 1000> - representing 1/1000.) The class tt(ratio) defines two directly accessible static data members: tt(num)hi(ratio: num) represents its numerator, tt(den)hi(ratio: den) its denominator. A tt(ratio) definition by itself simply defines a certain amount. E.g., when executing the following program verbinsert(-as4 examples/ratio.cc) the text 1,200 is displayed, as that's the `amount' represented by tt(ratio<5, 1000>): tt(ratio) simplifies the fraction whenever possible. A fairly large number of predefined tt(ratio) types exist. They are, like tt(ratio) itself, defined in the standard namespace and can be used instead of the more cumbersome tt(ratio) or tt(ratio) specification: tablecenter(8)(llcllcll)( rowline() row() row(cell(i(yocto)) cell(10+sups(-24)) cellq() cell(i(zepto)) cell(10+sups(-21)) cellq() cells(2)()) rowline() row() row(cell(i(atto)) cell(10+sups(-18)) cell() cell(i(femto)) cell(10+sups(-15)) cell() cell(i(pico)) cell(10+sups(-12))) row(cell(i(nano)) cell(10+sups(-9)) cell() cell(i(micro)) cell(10+sups(-6)) cell() cell(i(milli)) cell(10+sups(-3))) row(cell(i(centi)) cell(10+sups(-2)) cell() cell(i(deci)) cell(10+sups(-1))) rowline() row() row(cell(i(deca)) cell(10+sups(1)) cell() cell(i(hecto)) cell(10+sups(2)) cell() cell(i(kilo)) cell(10+sups(3))) row(cell(i(mega)) cell(10+sups(6)) cell() cell(i(giga)) cell(10+sups(9)) cell() cell(i(tera)) cell(10+sups(12))) row(cell(i(peta)) cell(10+sups(15)) cell() cell(i(exa)) cell(10+sups(18))) rowline() row() row(cell(i(zetta)) cell(10+sups(21)) cell() cell(i(yotta)) cell(10+sups(24))) rowline() ) (em(note:) the definitions of the types tt(yocto, zepto, zetta) and tt(yotta) use integral constants exceeding 64 bits. Although these constants are defined in bf(C++), they are not available on 64 bit or smaller architectures.) Time related ratios can very well be interpreted as fractions or multiple of seconds, with tt(ratio<1, 1>) representing a resolution of one second. Here is an example showing how these abbreviations can be used: verbinsert(-s4 //milli examples/milli.cc) c++-annotations-12.5.0/yo/namespaces/chrono/intro.yo0000644000175000017500000000764314466730207021253 0ustar frankfrankThe bf(C) programming language offers tools like bf(sleep)(3) and bf(select)(2) to suspend program execution for a certain amount of time. And of course the family of bf(time)(3) functions for setting and displaying time tt(Sleep) and tt(select) can be used for waiting, but as they were designed in an era when multi threading was unavailable, their usefulness is limited when used in multi threaded programs. Multi threading has become part of bf(C++) (covered in detail in chapter ref(THREADING)), and additional time-related functions are available in the tt(std::filesystem) namespace, covered below in this chapter. In multi threaded programs threads are frequently suspended, albeit usually for a very short time. E.g., when a thread wants to access a variable, but the variable is currently being updated by another thread, then the former thread should wait until the latter thread has completed the update. Updating a variable usually doesn't take much time, but if it takes an unexpectedly long time, then the former thread may want to be informed about that, so it can do something else while the latter thread is busy updating the variable. Interactions between threads like these cannot be realized with functions like tt(sleep) and tt(select). The hi(chrono)tt(std::chrono) namespace bridges the gap between the traditionally available time-related functions and the time-related requirements of multi-threading and of the tt(std::filesystem) name space. All but the specific tt(std::filesystem) related time functionality is available after including the tthi(chrono) header file. After including the tthi(filesystem) header file the facilities of the tt(std::filesystem) are available. Time can be measured in various resolutions: in Olympic games time differences of hundreds of seconds may make the distinction between a gold and silver medal, but when planning a vacation we might talk about months before we go on vacation. Time resolutions are specified through objects of the class tt(std::ratio), which (apart from including the tt() header file) is also available after including the tt() header file. Different events usually last for different amounts of time (given a specific time resolution). Amounts of time are specified through objects of the class tt(std::chrono::duration). Events can also be characterized by their points in time: midnight, January 1, 1970 GMT is a point in time, as is 19:00, December 5, 2010. Points in time are specified through objects of the class tt(std::chrono::time_point). It's not just that resolutions, durations of events, and points in time of events may differ, but the devices (clocks) we use for specifying time also differ. In the old days em(hour glasses) were used (and sometimes they're still used when boiling eggs), but on the other hand we may use atomic clocks when measurements should be very precise. Four different types of clocks are available. The commonly used clock is tt(std::chrono::system_clock), but in the context of the file system there's also an (implicitly defined) tt(filesystem::__file_clock). In the upcoming sections the details of the tt(std::chrono) namespace are covered. First we look at characteristics of time resolutions. How to handle amounts of time given their resolutions is covered next. The next section describes facilities for defining and handling time-points. The relationships between these types and the various clock-types are covered thereafter. In this chapter the specification tt(std::chrono::) is often omitted (in practice tt(using namespace std) followed by tt(using namespace chrono) is commonly used; tt([std::]chrono::) specifications are occasionally used to avoid ambiguities). Also, every now and then you'll encounter em(forward references) to later chapters, like the reference to the chapter about multi-threading. These are hard to avoid, but studying those chapters at this point fortunately can be postponed without loss of continuity. c++-annotations-12.5.0/yo/namespaces/chrono/duration.yo0000644000175000017500000001156714466730207021745 0ustar frankfrankAmounts of time are specified through objects of the class hi(duration)tt(std::chrono::duration). Before using the class tt(duration) the tthi(chrono) header file must be included. Like tt(ratio) the class tt(duration) requires two template arguments. A numeric type (tt(int64_t) is normally used) defining the type holding the duration's amount of time, and a time-resolution (called its em(resolution)), usually specified through a tt(std::ratio)-type (often using one of its tt(chrono) abbreviations). Using the predefined tt(std::deca ratio), representing units of 10 seconds an interval of 30 minutes is defined as follows: verb( duration halfHr(180);) Here tt(halfHr) represents a time interval of 180 deca-seconds, so 1800 seconds. Comparable to the predefined ratios predefined duration types are available: center( tbl(lll)(\ tline()()\ tr(tc(i(nanoseconds))tc(nbsp())tc(tt(duration)))\ tr(tc(i(microseconds))tc(nbsp())tc(tt(duration)))\ tr(tc(i(milliseconds))tc(nbsp())tc(tt(duration)))\ tr(tc(i(seconds))tc(nbsp())tc(tt(duration)))\ tr(tc(i(minutes))tc(nbsp())tc(tt(duration>)))\ tr(tc(i(hours))tc(nbsp())tc(tt(duration>)))\ tline()()\ )) Using these types, a time amount of 30 minutes can now simply be defined as tt(minutes halfHour(30)). The two types that were specified when defining a tt(duration) can be retrieved as, respectively, itemization( itt(rep), which is equivalent to the numeric type (like tt(int64_t)). E.g., tt(seconds::rep) is equivalent to tt(int64_t); itt(period), which is equivalent to the tt(ratio) type (like tt(kilo)) and so tt(duration::period::num) is equal to 1000. ) COMMENT(all constexpr, the constructor: explicit) Duration objects can be constructed by specifying an argument of its numeric type: itemization( itt(duration(Type const &value)):nl() a specific duration of tt(value) time units. tt(Type) refers to the duration's numeric type (e.g., tt(int64_t)). So, when defining verb( minutes halfHour(30);) the argument 30 is stored inside its tt(int64_t) data member. ) Duration supports copy- and move-constructors (cf. chapter ref(MEMORY)) and its default constructor initializes its tt(int64_t) data member to zero. The amount of time stored in a duration object may be modified by adding or subtracting two duration objects or by multiplying, dividing, or computing a modulo value of its data member. Numeric multiplication operands may be used as left-hand side or right-hand side operands; in combination with the other multiplication operators the numeric operands must be used as right-hand side operands. Compound assignment operators are also available. Some examples: verb( minutes fullHour = minutes{ 30 } + halfHour; fullHour = 2 * halfHour; halfHour = fullHour / 2; fullHour = halfHour + halfHour; halfHour /= 2; halfHour *= 2;) In addition, tt(duration) offers the following members (the first member is an ordinary member function requiring a tt(duration) object). The other three are static members (cf. chapter ref(StaticDataFun)) which can be used without requiring objects (as shown at the tt(zero) code snippet): itemization( itt(Type count() const) returns the value that is stored inside the tt(duration) object's data member. For tt(halfHour) it returns 30, not 1800; itt(duration::zero()):nl() this is an (immutable) duration object whose tt(count) member returns 0. E.g.: verb( seconds::zero().count(); // equals int64_t 0) itt(duration::min()):nl() an immutable duration object whose tt(count) member returns the lowest value of its tt(Type) (i.e., tt(std::numeric_limits::min()) (cf. section ref(NUMLIM))); itt( duration::max()):nl() an immutable duration object whose tt(count) member returns the lowest value of its tt(Type) (i.e., tt(std::numeric_limits::max())). ) Duration objects using different resolutions may be combined as long as no precision is lost. When duration objects using different resolutions are combined the resulting resolution is the finer of the two. When compound binary operators are used the receiving object's resolution must be the finer or the compilation fails. verb( minutes halfHour{ 30 }; hours oneHour{ 1 }; cout << (oneHour + halfHour).count(); // displays: 90 halfHour += oneHour; // OK // oneHour += halfHours; // won't compile) The suffixes tt(h, min, s, ms, us, ns) can be used for integral values, creating the corresponding tt(duration) time intervals. E.g., tt(minutes min = 1h) stores 60 in tt(min). c++-annotations-12.5.0/yo/namespaces/outside.yo0000644000175000017500000000654314466730207020302 0ustar frankfrankIt is not strictly necessary to i(define members of namespaces) inside a namespace region. But before an entity is defined em(outside) of a namespace it must have been declared em(inside) its namespace. To define an entity outside of its namespace its name must be em(fully qualified) by prefixing the member by its namespaces. The definition may be provided at the global level or at intermediate levels in the case of nested namespaces. This allows us to define an entity belonging to namespace tt(A::B) within the region of namespace tt(A). Assume the type tt(int INT8[8]) is defined in the tt(CppAnnotations::Virtual) namespace. Furthermore assume that it is our intent to define a function tt(squares), inside the namespace nl() tt(CppAnnotations::Virtual) returning a pointer to tt(CppAnnotations::Virtual::INT8). Having defined the prerequisites within the tt(CppAnnotations::)tt(Virtual) namespace, our function could be defined as follows (cf. chapter ref(MEMORY) for coverage of the memory allocation operator tt(new[])): verb( namespace CppAnnotations { namespace Virtual { void *pointer; using INT8 = int[8]; INT8 *squares() { INT8 *ip = new INT8[1]; for (size_t idx = 0; idx != sizeof(INT8) / sizeof(int); ++idx) (*ip)[idx] = (idx + 1) * (idx + 1); return ip; } } }) The function tt(squares) defines an array of one tt(INT8) vector, and returns its address after initializing the vector by the squares of the first eight natural numbers. Now the function tt(squares) can be defined outside of the tt(CppAnnotations::)tt(Virtual) namespace: verb( namespace CppAnnotations { namespace Virtual { void *pointer; using INT8 = int[8]; INT8 *squares(); } } CppAnnotations::Virtual::INT8 *CppAnnotations::Virtual::squares() { INT8 *ip = new INT8[1]; for (size_t idx = 0; idx != sizeof(INT8) / sizeof(int); ++idx) (*ip)[idx] = (idx + 1) * (idx + 1); return ip; }) In the above code fragment note the following: itemization( itt(squares) is declared inside of the tt(CppAnnotations::Virtual) namespace. itt() The definition outside of the namespace region requires us to use the fully qualified name of the function em(and) of its return type. itt() em(Inside) the body of the function tt(squares) we are within the tt(CppAnnotations::)tt(Virtual) namespace, so inside the function fully qualified names (e.g., for tt(INT8)) are not required any more. ) Finally, note that the function could also have been defined in the tt(CppAnnotations) region. In that case the tt(Virtual) namespace would have been required when defining tt(squares()) and when specifying its return type, while the internals of the function would remain the same: verb( namespace CppAnnotations { namespace Virtual { void *pointer; using INT8 = int[8]; INT8 *squares(); } Virtual::INT8 *Virtual::squares() { INT8 *ip = new INT8[1]; for (size_t idx = 0; idx != sizeof(INT8) / sizeof(int); ++idx) (*ip)[idx] = (idx + 1) * (idx + 1); return ip; } }) c++-annotations-12.5.0/yo/namespaces/closed.yo0000644000175000017500000000133614466730207020072 0ustar frankfrankNamespaces can be defined without a name. Such an hi(namespace: anonymous) anonymous namespace restricts the visibility of the defined entities to the source file defining the anonymous namespace. Entities defined in the anonymous namespace are comparable to bf(C)'s ti(static) functions and variables. In bf(C++) the tt(static) keyword can still be used, but its preferred use is in tt(class) definitions (see chapter ref(Classes)). In situations where in bf(C) static variables or functions would have been used the anonymous namespace should be used in bf(C++). The anonymous namespace is a hi(namespace: closed) closed namespace: it is not possible to add entities to the same anonymous namespace using different source files. c++-annotations-12.5.0/yo/namespaces/directive.yo0000644000175000017500000000365714522250215020574 0ustar frankfrankA generalized alternative to the tt(using) declaration is the emi(using directive): verb( using namespace CppAnnotations;) Following this directive, em(all) entities defined in the tt(CppAnnotations) namespace are used as if they were declared by tt(using) declarations. While the tt(using) directive is a quick way to hi(namespace: import all names) import all the names of a namespace (assuming the namespace has previously been declared or defined), it is at the same time a somewhat dirty way to do so, as it is less clear what entity is actually used in a particular block of code. If, e.g., tt(cos) is defined in the tt(CppAnnotations) namespace, tt(CppAnnotations::cos) is going to be used when tt(cos) is called. However, if tt(cos) is em(not) defined in the tt(CppAnnotations) namespace, the standard tt(cos) function will be used. The tt(using) directive does not document as clearly as the tt(using) declaration what entity will actually be used. Therefore use caution when applying the tt(using) directive. Namespace declarations are context sensitive: when a tt(using namespace) declaration is specified inside a compound statement then the declaration is valid until the compound statement's closing curly brace has been encountered. In the next example a string tt(first) is defined without explicit specifying tt(std::string), but once the compound statement has ended the scope of the tt(using namespace std) declaration has also ended, and so tt(std::) is required once again when defining tt(second): verb( #include int main() { { using namespace std; string first; } std::string second; }) A tt(using namespace) directive cannot be used within the declaration block of a class- or enumeration-type. E.g., the following example won't compile: verb( struct Namespace { using namespace std; // won't compile };) c++-annotations-12.5.0/yo/concrete/0000755000175000017500000000000014522250255015721 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fdunget.yo0000644000175000017500000001056114466730207017740 0ustar frankfranktt(Streambuf) classes and classes derived from ti(streambuf) should support em(at least) ungetting the last read character. Special care must be taken when em(series) of ti(unget) calls must be supported. In this section the construction of a class supporting a configurable number of tt(istream::unget) or hi(putback)tt(istream::putback) calls is discussed. Support for multiple (say `tt(n)') tt(unget) calls is implemented by reserving an initial section of the input buffer, which is gradually filled up to contain the last tt(n) characters read. The class is implemented as follows: itemization( it() Once again, the class is derived from tt(std::streambuf). It defines several data members, allowing the class to perform the bookkeeping required to maintain an unget-buffer of a configurable size: verbinclude(//CLASS examples/fdunget.h) it() The class's constructor expects a i(file descriptor), a buffer size and the number of characters that can be ungot or pushed back as its arguments. This number determines the size of a em(reserved) area, defined as the first tt(d_reserved) bytes of the class's input buffer. itemization( it() The input buffer will always be at least one byte larger than tt(d_reserved). So, a certain number of bytes may be read. Once tt(d_reserved) bytes have been read at most tt(d_reserved) bytes can be ungot. it() Next, the starting point for reading operations is configured. It is called tt(d_base), pointing to a location tt(d_reserved) bytes beyond the location represented by tt(d_buffer). This is always the location where buffer refills start. it() Now that the buffer has been constructed, we're ready to define tt(streambuf)'s buffer pointers using tt(setg). As no characters have been read yet, all pointers are set to point to tt(d_base). If tt(unget) is called at this point, no characters are available, and tt(unget) (correctly) fails. it() Eventually, the refill buffer's size is determined as the number of allocated bytes minus the size of the reserved area. ) Here is the class's constructor: verbinclude(//CONS examples/fdunget.h) it() The class's destructor simply returns the memory allocated for the buffer to the common pool: verbinclude(//DESTR examples/fdunget.h) it() Finally, tt(underflow) is overridden as follows: itemization( it() First tt(underflow) determines the number of characters that could potentially be ungot. If that number of characters are ungot, the input buffer is exhausted. So this value may be any value between 0 (the initial state) or the input buffer's size (when the reserved area has been filled up completely, and all current characters in the remaining section of the buffer have also been read); it() Next the number of bytes to move into the reserved area is computed. This number is at most tt(d_reserved), but it is set equal to the actual number of characters that can be ungot if this value is smaller; it() Now that the number of characters to move into the reserved area is known, this number of characters is moved from the input buffer's end to the area immediately before tt(d_base); it() Then the buffer is refilled. This all is standard, but notice that reading starts from tt(d_base) and not from tt(d_buffer); it() Finally, tt(streambuf)'s read buffer pointers are set up. hi(eback) tt(Eback) is set to tt(move) locations before tt(d_base), thus defining the guaranteed unget-area, ti(gptr) is set to tt(d_base), since that's the location of the first read character after a refill, and ti(egptr) is set just beyond the location of the last character read into the buffer. ) Here is tt(underflow)'s implementation: verbinclude(//UNDERFLOW examples/fdunget.h) ) bf(An example using FdUnget) The next example program illustrates the use of the class tt(FdUnget). It reads at most 10 characters from the standard input, stopping at endOfFile(). A guaranteed unget-buffer of 2 characters is defined in a buffer holding 3 characters. Just before reading a character, the program tries to unget at most 6 characters. This is, of course, not possible; but the program nicely ungets as many characters as possible, considering the actual number of characters read: verbinclude(-a examples/fdunget.cc) c++-annotations-12.5.0/yo/concrete/predicates.yo0000644000175000017500000000711514466730207020430 0ustar frankfrankMany tt(STL) algorithms require us to specify predicates. For example tt(count_if()) (ref(COUNT)), tt(find_if()) (ref(FIND)), tt(min_element()) (ref(MINEL)) or tt(search()) (ref(SEARCH)). In these cases a function object must be provided whose tt(operator()()) member is called, defining the predicate function. Conditional to its argument(s), it returns tt(true) or tt(false). Sometimes a simple emi(predicate function) already exists. For example tt(int isdigit(int)) returns if its argument is a character representing a digit, otherwise 0; tt(char *strchr(char const *, int)) returns a non-0 pointer if the set of characters provided as its first argument contains the character represented by its second argument, and returns 0 otherwise. Existing unary predicate functions may be specified with the tt(PredicateFunction1) class template, defining a unary predicate class. Its ti(argument_type) using-declaration is required by, e.g., function adapters: verbinclude(//UNARYPRED examples/predicates.h) Existing binary predicate functions may be specified with the tt(PredicateFunction2) class template, defining a binary predicate class. Its ti(first_argument_type), ti(second_argument_type) and ti(result_type) using-declarations are required by, e.g., function adapters: verbinclude(//BINPRED examples/predicates.h) Here is an example of their use, counting the number of digits appearing at the program's standard input stream: verbinclude(-a examples/predfun.cc) Alternatively, although the function operator is called when a predicate function is used, the actual member function we have available might be another function or a useful member may be available from an object of another class. In that case an object acting as em(man in the middle) might come in handy. The following class tt(PredicateObject1) performs exactly that function. It defines a class template whose parameters refer to a class and a data type. Its constructors expect a pointer or reference to an object of the template parameter's class as well as a pointer to a member function of that class implementing a predicate. By default it's the class's function object operator. Here is its definition: verbinclude(//PREDOBJ1 examples/predicates.h) The class tt(PredicateObject2) can be used to construct a emi(binary predicate) object. Here the class template has three parameters: the class type of the object passed to its constructor as well as the types of the two arguments of the binary predicate member that's called: verbinclude(//PREDOBJ2 examples/predicates.h) The object passed to these constructors is not copied by generic algorithms, in contrast to the tt(PredicateObject)s themselves, which em(are) copied. The object specified when instantiating the tt(PredicateObject)s must actually exist before the instantiation takes place. Also, the object's members do not have to be tt(const) member functions, thus allowing modifications of the passed object's data. Function adapters may be used with the tt(PredicateObject)s as well. Here is an example using tt(PredicateObject)s. The program counts the number of words containing vowels appearing at the program's standard input stream. First a support class tt(Contains) is defined. It's a simple class defining unary and binary predicate functions: verbinclude(//CONTAINS examples/predobj.cc) When the program is called without arguments its unary predicate object functionality is used, otherwise its binary predicate object functionality. Here is the program's tt(main()) function: verbinclude(//MAIN examples/predobj.cc) c++-annotations-12.5.0/yo/concrete/examples/0000755000175000017500000000000014624637124017546 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/examples/fork.h0000664000175000017500000000105414624637127020665 0ustar frankfrank//CLASS class Fork { int d_pid; public: virtual ~Fork(); void fork(); protected: int pid() const; int waitForChild(); // returns the status private: virtual void childRedirections(); virtual void parentRedirections(); virtual void childProcess() = 0; // pure virtual members virtual void parentProcess() = 0; }; //= //PID inline int Fork::pid() const { return d_pid; } //= c++-annotations-12.5.0/yo/concrete/examples/ifdnbuf.h0000664000175000017500000000424114624637127021342 0ustar frankfrank #ifndef IFDNBUF_H_ #define IFDNBUF_H_ #include #include #include //CLASS class IFdNStreambuf: public std::streambuf { protected: int d_fd = -1; size_t d_bufsize = 0; char* d_buffer = 0; public: IFdNStreambuf() = default; IFdNStreambuf(int fd, size_t bufsize = 1); ~IFdNStreambuf() override; void open(int fd, size_t bufsize = 1); private: int underflow() override; std::streamsize xsgetn(char *dest, std::streamsize n) override; }; //= //CONS inline IFdNStreambuf::IFdNStreambuf(int fd, size_t bufsize) { open(fd, bufsize); } //= // In real applications, the following members should be defined in // source files. Headers should not have external linkage. //DESTR IFdNStreambuf::~IFdNStreambuf() { if (d_bufsize) { close(d_fd); delete[] d_buffer; } } //= //OPEN void IFdNStreambuf::open(int fd, size_t bufsize) { d_fd = fd; d_bufsize = bufsize == 0 ? 1 : bufsize; delete[] d_buffer; d_buffer = new char[d_bufsize]; setg(d_buffer, d_buffer + d_bufsize, d_buffer + d_bufsize); } //= //UFLOW int IFdNStreambuf::underflow() { if (gptr() < egptr()) return *gptr(); int nread = read(d_fd, d_buffer, d_bufsize); if (nread <= 0) return EOF; setg(d_buffer, d_buffer, d_buffer + nread); return static_cast(*gptr()); } //= //XSGETN std::streamsize IFdNStreambuf::xsgetn(char *dest, std::streamsize n) { int nread = 0; while (n) { if (!in_avail()) { if (underflow() == EOF) break; } int avail = in_avail(); if (avail > n) avail = n; memcpy(dest + nread, gptr(), avail); gbump(avail); nread += avail; n -= avail; } return nread; } //= #endif c++-annotations-12.5.0/yo/concrete/examples/lines0.h0000664000175000017500000000034714624637127021122 0ustar frankfrank #include #include //LINES class Lines { std::vector d_line; public: Lines(std::istream &in); std::string &operator[](size_t idx); }; //= c++-annotations-12.5.0/yo/concrete/examples/buildslurp0000755000175000017500000000010714466730207021657 0ustar frankfrank#!/bin/bash g++ -Wall parentslurp.cc fork.cc pipe.cc waitforchild.cc c++-annotations-12.5.0/yo/concrete/examples/fdout.cc0000664000175000017500000000143714624637130021202 0ustar frankfrank #include #include #include #include "fdout.h" using namespace std; int main(int argc, char **argv) { OFdnStreambuf fds(STDOUT_FILENO, 500); ostream os(&fds); switch (argc) { case 1: for (string s; getline(cin, s); ) os << s << '\n'; os << "COPIED cin LINE BY LINE\n"; break; case 2: cin >> os.rdbuf(); // Alternatively, use: cin >> &fds; os << "COPIED cin BY EXTRACTING TO os.rdbuf()\n"; break; case 3: os << cin.rdbuf(); os << "COPIED cin BY INSERTING cin.rdbuf() into os\n"; break; } } c++-annotations-12.5.0/yo/concrete/examples/fdunget.cc0000664000175000017500000000402014624637130021504 0ustar frankfrank #include "fdunget.h" #include #include #include using namespace std; int main() { FdUnget fds(0, 3, 2); istream is(&fds); char c; for (int idx = 0; idx < 10; ++idx) { cout << "after reading " << idx << " characters:\n"; for (int ug = 0; ug <= 6; ++ug) { if (!is.unget()) { cout << "\tunget failed at attempt " << (ug + 1) << "\n" << "\trereading: '"; is.clear(); while (ug--) { is.get(c); cout << c; } cout << "'\n"; break; } } if (!is.get(c)) { cout << " reached\n"; break; } cout << "Next character: " << c << '\n'; } } /* Generated output after 'echo abcde | program': after reading 0 characters: unget failed at attempt 1 rereading: '' Next character: a after reading 1 characters: unget failed at attempt 2 rereading: 'a' Next character: b after reading 2 characters: unget failed at attempt 3 rereading: 'ab' Next character: c after reading 3 characters: unget failed at attempt 4 rereading: 'abc' Next character: d after reading 4 characters: unget failed at attempt 4 rereading: 'bcd' Next character: e after reading 5 characters: unget failed at attempt 4 rereading: 'cde' Next character: after reading 6 characters: unget failed at attempt 4 rereading: 'de ' reached */ c++-annotations-12.5.0/yo/concrete/examples/foreach.h0000664000175000017500000000205514624637127021335 0ustar frankfrank //FOREACH1 template Class &ForEach(Iterator begin, Iterator end, Class &object, void (Class::*member)(Data &)) { while (begin != end) (object.*member)(*begin++); return object; } //= //FOREACH2 template Class &ForEach(Iterator begin, Iterator end, Class &object, void (Class::*member)(Data &) const) { while (begin != end) (object.*member)(*begin++); return object; } //= //FOREACH3 template Class &ForEach(Iterator begin, Iterator end, Class &object) { while (begin != end) object(*begin++); return object; } //= //FOREACH4 template void ForEach(Iterator begin, Iterator end, Data(*function)(Data)) { for (; begin != end; ++begin) *begin = function(*begin); } //= c++-annotations-12.5.0/yo/concrete/examples/fork.ih0000664000175000017500000000017214624637127021036 0ustar frankfrank #include "fork.h" #include #include #include #include c++-annotations-12.5.0/yo/concrete/examples/predfun.cc0000664000175000017500000000206314624637131021521 0ustar frankfrank #include #include #include #include #include #include #include "predicates.h" using namespace std; int main(int argc, char **argv) { if (argc == 1) cout << "Counted " << count_if(istream_iterator(cin), istream_iterator(), PredicateFunction1(isdigit)) << " digits\n"; else cout << "Counted " << count_if(istream_iterator(cin), istream_iterator(), bind1st( PredicateFunction2(strchr), "0123456789") ) << " digits\n"; } /* Generated output after echo 1 world, there are 6 continents and 3 oceans | a.out or: echo 1 world, there are 6 continents and 3 oceans | a.out 2 Counted 3 digits */ c++-annotations-12.5.0/yo/concrete/examples/command.h0000664000175000017500000000062414624637127021344 0ustar frankfrank #include #include #include class Command { std::string d_line; std::vector d_command; public: Command(size_t n, char const **commands) { copy(commands, commands + n, back_inserter(d_command)); } int next(std::string &line); }; c++-annotations-12.5.0/yo/concrete/examples/fdout.h0000664000175000017500000000300314624637127021041 0ustar frankfrank #ifndef OFDNSTREAMBUF_H_ #define OFDNSTREAMBUF_H_ #include #include //CLASS class OFdnStreambuf: public std::streambuf { int d_fd = -1; size_t d_bufsize = 0; char *d_buffer = 0; public: OFdnStreambuf() = default; OFdnStreambuf(int fd, size_t bufsize = 1); ~OFdnStreambuf() override; void open(int fd, size_t bufsize = 1); private: int sync() override; int overflow(int c) override; }; //= //CONS inline OFdnStreambuf::OFdnStreambuf(int fd, size_t bufsize) { open(fd, bufsize); } //= //DESTR inline OFdnStreambuf::~OFdnStreambuf() { if (d_buffer) { sync(); delete[] d_buffer; } } //= //OPEN inline void OFdnStreambuf::open(int fd, size_t bufsize) { d_fd = fd; d_bufsize = bufsize == 0 ? 1 : bufsize; delete[] d_buffer; d_buffer = new char[d_bufsize]; setp(d_buffer, d_buffer + d_bufsize); } //= //SYNC inline int OFdnStreambuf::sync() { if (pptr() > pbase()) { write(d_fd, d_buffer, pptr() - pbase()); setp(d_buffer, d_buffer + d_bufsize); } return 0; } //= //OVERFLOW inline int OFdnStreambuf::overflow(int c) { sync(); if (c != EOF) { *pptr() = c; pbump(1); } return c; } //= #endif c++-annotations-12.5.0/yo/concrete/examples/lines.h0000664000175000017500000000227114624637127021040 0ustar frankfrank#include #include #include #include //LINES class Lines { std::vector d_line; public: class Proxy; Proxy operator[](size_t idx); class Proxy { friend Proxy Lines::operator[](size_t idx); std::string &d_str; Proxy(std::string &str); public: std::string &operator=(std::string const &rhs); operator std::string const &() const; }; Lines(std::istream &in); }; //= //MEMBERS inline Lines::Proxy::Proxy(std::string &str) : d_str(str) {} inline std::string &Lines::Proxy::operator=(std::string const &rhs) { return d_str = rhs; } inline Lines::Proxy::operator std::string const &() const { return d_str; } //= //INSERT inline std::ostream &operator<<(std::ostream &out, Lines::Proxy const &proxy) { return out << static_cast(proxy); } //= //OPIDX inline Lines::Proxy Lines::operator[](size_t idx) { Proxy ret(d_line[idx]); return ret; } //= c++-annotations-12.5.0/yo/concrete/examples/a2x.h0000664000175000017500000000232714624637127020422 0ustar frankfrank#ifndef INCLUDED_A2X_H_ #define INCLUDED_A2X_H_ #include #include //CLASS class A2x: public std::istringstream { public: A2x() = default; A2x(char const *txt); A2x(std::string const &str); template operator Type(); template Type to(); A2x &operator=(char const *txt); A2x &operator=(std::string const &str); A2x &operator=(A2x const &other); }; //= //CONS inline A2x::A2x(char const *txt) // initialize from text : std::istringstream(txt) {} inline A2x::A2x(std::string const &str) : std::istringstream(str.c_str()) {} //= //TO template inline Type A2x::to() { Type t; return (*this >> t) ? t : Type(); } //= //TYPE template inline A2x::operator Type() { return to(); } //= inline A2x &A2x::operator=(std::string const &str) { return operator=(str.c_str()); } //OP= inline A2x &A2x::operator=(A2x const &other) { return operator=(other.str()); } //= #endif c++-annotations-12.5.0/yo/concrete/examples/rsh.cc0000664000175000017500000000262614624637131020657 0ustar frankfrank #include #include #include #include #include using namespace std; int main() { while (true) { string cmd; cout << "rsh: " << flush; cin >> cmd; if (cmd == "exit") { cout << "terminating the shell\n"; return 0; } if (cmd != "date" && cmd != "id") { cout << "Command " << cmd << " disallowed\n"; continue; } pid_t pid = fork(); if (pid == 0) { execlp(cmd.c_str(), cmd.c_str(), 0); cerr << "Execution of " << cmd << " failed\n"; return 1; } if (pid < 0) { cerr << "Fork() failed\n"; return 1; } int status; wait(&status); if ((status = WEXITSTATUS(status))) cerr << cmd << " returned exit status " << status << '\n'; } } /* Example of generated conversation: rsh: opa Command opa disallowed rsh: date Tue Jul 17 23:19:08 CEST 2001 rsh: id uid=405(frank) gid=100(users) groups=100(users),4(adm) rsh: quit Command quit disallowed rsh: exit terminating the shell */ c++-annotations-12.5.0/yo/concrete/examples/binopclasses.cc0000664000175000017500000000612614624637130022546 0ustar frankfrank#include #include #include // The complete interface of the class template Binops: if additional // operators are overloaded Binops requires no modifications. // template class Binops { template friend std::ostream &operator<<( std::ostream &out, Binops const &rhs); template friend std::istream &operator>>(std::istream &in, Binops &rhs); void eWrap(std::istream &in); void iWrap(std::ostream &out) const; }; // Completing the overloads for operator+: all function templates, that // depend on operator+=(...) defined in Derived // template Derived &operator+=(Binops &lhs, Rhs const &rhs) { Derived tmp{ Derived{static_cast(lhs)} += rhs }; tmp.swap(static_cast(lhs)); return static_cast(lhs); } template Derived operator+(Binops &&lhs, Rhs const &rhs) { return static_cast(std::move(lhs)) += rhs; } template Derived operator+(Binops const &lhs, Rhs const &rhs) { return Derived{static_cast(lhs)} += rhs; } // Other operators may be added here, and are implemented analogously, see // the Annotations. // Implementing the insertion operator. The extraction operator is // implemented analogously, see the Annotations: // template inline void Binops::iWrap(std::ostream &out) const { static_cast(*this).insert(out); } template inline std::ostream &operator<<(std::ostream &out, Binops const &rhs) { rhs.iWrap(out); return out; } //////////////////////////////////////////////////////////////////////// // User area: the user defines a class Derived, and wants to provide // addition and insertion: the operator+=() && and insert() functions have // to be implemented and Derived derives from Binops. For insert // a friend declaration is also required. #include using namespace std; class Derived: public Binops { friend Binops; // only required for stream insertion/extraction int d_value = 0; public: Derived() = default; Derived(int value) : d_value(value) {} void swap(Derived &other); Derived &&operator+=(Derived const &rhs) &&; private: void insert(std::ostream &out) const; }; inline void Derived::insert(std::ostream &out) const { out << "Inserting a Derived object"; } Derived &&Derived::operator+=(Derived const &rhs) && { d_value += rhs.d_value; return std::move(*this); } inline void Derived::swap(Derived &rhs) { std::swap(d_value, rhs.d_value); } int main() { Derived o1{ 1 }, Derived o2{ 2 }; o1 += o2; // o1 *= o2; // adding this statement results in // a compilation error o1 = o1 + o2; o1 += o1; cout << o1 << '\n'; } c++-annotations-12.5.0/yo/concrete/examples/pipe.cc0000664000175000017500000000164514624637131021020 0ustar frankfrank #include "pipe.h" #include //CONS Pipe::Pipe() { if (pipe(d_fd)) throw "Pipe::Pipe(): pipe() failed"; } //= //REDIRECT void Pipe::redirect(int d_fd, int alternateFd) { if (dup2(d_fd, alternateFd) < 0) throw "Pipe: redirection failed"; } //= //READ int Pipe::readOnly() { close(d_fd[WRITE]); return d_fd[READ]; } void Pipe::readFrom(int fd) { readOnly(); redirect(d_fd[READ], fd); close(d_fd[READ]); } //= //WRITE int Pipe::writeOnly() { close(d_fd[READ]); return d_fd[WRITE]; } void Pipe::writtenBy(int fd) { writtenBy(&fd, 1); } void Pipe::writtenBy(int const *fd, size_t n) { writeOnly(); for (size_t idx = 0; idx < n; idx++) redirect(d_fd[WRITE], fd[idx]); close(d_fd[WRITE]); } //= c++-annotations-12.5.0/yo/concrete/examples/iterators/0000755000175000017500000000000014624637124021562 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/examples/iterators/output.cc0000664000175000017500000000025314624637131023431 0ustar frankfrank#include "input.h" #include "output.h" #include using namespace std; int main() { copy(InputIterator{ 0 }, InputIterator{ 100 }, OutputIterator{ 0 }); } c++-annotations-12.5.0/yo/concrete/examples/iterators/random.h0000664000175000017500000000367414624637127023232 0ustar frankfrank #include struct RandomIterator { using iterator_category = std::bidirectional_iterator_tag; using difference_type = std::ptrdiff_t; using value_type = int; using pointer = value_type *; using reference = value_type &; private: int d_value; public: RandomIterator(int init); // standard: bool operator==(RandomIterator const &other) const; bool operator!=(RandomIterator const &other) const; int &operator*(); RandomIterator &operator++(); // required: int operator-(RandomIterator const &rhs) const; RandomIterator operator+(int step) const; RandomIterator operator-(int step) const; bool operator<(RandomIterator const &other) const; // consider: int *operator->() const; RandomIterator &operator--(); RandomIterator operator--(int); RandomIterator operator++(int); RandomIterator &operator-=(int step); RandomIterator &operator+=(int step); }; RandomIterator::RandomIterator(int init) : d_value(init) {} bool RandomIterator::operator!=(RandomIterator const &other) const { return d_value != other.d_value; } bool RandomIterator::operator==(RandomIterator const &other) const { return d_value == other.d_value; } bool RandomIterator::operator<(RandomIterator const &other) const { return d_value < other.d_value; } int RandomIterator::operator-(RandomIterator const &rhs) const { return 0; } RandomIterator RandomIterator::operator+(int step) const { return *this; } RandomIterator RandomIterator::operator-(int step) const { return *this; } RandomIterator &RandomIterator::operator--() { return *this; } RandomIterator &RandomIterator::operator++() { return *this; } int &RandomIterator::operator*() { return d_value; } c++-annotations-12.5.0/yo/concrete/examples/iterators/forward.cc0000664000175000017500000000022114624637131023530 0ustar frankfrank#include "forward.h" #include using namespace std; int main() { adjacent_find(ForwardIterator{ 0 }, ForwardIterator{ 100 }); } c++-annotations-12.5.0/yo/concrete/examples/iterators/iterator.h0000664000175000017500000000262714624637127023600 0ustar frankfrank #include struct RandomIterator { using iterator_category = std::bidirectional_iterator_tag; using difference_type = std::ptrdiff_t; using value_type = int; using pointer = value_type *; using reference = value_type &; private: int d_value; public: RandomIterator(int init); bool operator==(RandomIterator const &other) const; int operator-(RandomIterator const &rhs) const; RandomIterator operator+(int step) const; RandomIterator &operator--() int &operator*(); int *operator->() const; bool operator<(RandomIterator const &other) const; RandomIterator operator--(int); RandomIterator &operator++(); RandomIterator operator++(int); RandomIterator operator-(int step) const; RandomIterator &operator-=(int step); RandomIterator &operator+=(int step); }; RandomIterator::RandomIterator(int init) : d_value(init) {} bool RandomIterator::operator!=(RandomIterator const &other) const { return d_value != other.d_value; } int RandomIterator::operator-(RandomIterator const &rhs) const { return 0; } RandomIterator &RandomIterator::operator--() { return *this; } int &RandomIterator::operator*() { return d_value; } c++-annotations-12.5.0/yo/concrete/examples/iterators/bidirectional.h0000664000175000017500000000245514624637127024556 0ustar frankfrank #include struct BidirectionalIterator { using iterator_category = std::bidirectional_iterator_tag; using difference_type = std::ptrdiff_t; using value_type = int; using pointer = value_type *; using reference = value_type &; private: int d_value; public: BidirectionalIterator(int init); // standard: bool operator==(BidirectionalIterator const &other) const; bool operator!=(BidirectionalIterator const &other) const; int &operator*(); BidirectionalIterator &operator++(); // required: BidirectionalIterator &operator--(); // consider: int *operator->(); }; BidirectionalIterator::BidirectionalIterator(int init) : d_value(init) {} bool BidirectionalIterator::operator!=(BidirectionalIterator const &other) const { return d_value != other.d_value; } bool BidirectionalIterator::operator==(BidirectionalIterator const &other) const { return d_value == other.d_value; } BidirectionalIterator &BidirectionalIterator::operator++() { return *this; } BidirectionalIterator &BidirectionalIterator::operator--() { return *this; } int &BidirectionalIterator::operator*() { return d_value; } c++-annotations-12.5.0/yo/concrete/examples/iterators/bidirectional.cc0000664000175000017500000000050214624637131024676 0ustar frankfrank#include "bidirectional.h" #include using namespace std; int main() { inplace_merge(BidirectionalIterator{ 0 }, BidirectionalIterator{ 100 }, BidirectionalIterator{ 200 }); next_permutation(BidirectionalIterator{ 0 }, BidirectionalIterator{ 100 }); } c++-annotations-12.5.0/yo/concrete/examples/iterators/input.cc0000664000175000017500000000021114624637131023222 0ustar frankfrank#include "input.h" #include using namespace std; int main() { accumulate(InputIterator{ 0 }, InputIterator{ 100 }, 0); } c++-annotations-12.5.0/yo/concrete/examples/iterators/input.h0000664000175000017500000000211014624637127023071 0ustar frankfrank #include struct InputIterator { using iterator_category = std::input_iterator_tag; using difference_type = std::ptrdiff_t; using value_type = int; using pointer = value_type *; using reference = value_type &; private: int d_value; public: InputIterator(int init); // standard: bool operator==(InputIterator const &other) const; bool operator!=(InputIterator const &other) const; int const &operator*() const; InputIterator &operator++(); // consider: int const *operator->() const; }; InputIterator::InputIterator(int init) : d_value(init) {} bool InputIterator::operator!=(InputIterator const &other) const { return d_value != other.d_value; } bool InputIterator::operator==(InputIterator const &other) const { return d_value == other.d_value; } InputIterator &InputIterator::operator++() { return *this; } int const &InputIterator::operator*() const { return d_value; } c++-annotations-12.5.0/yo/concrete/examples/iterators/output.h0000664000175000017500000000206314624637127023301 0ustar frankfrank #include struct OutputIterator { using iterator_category = std::output_iterator_tag; using difference_type = std::ptrdiff_t; using value_type = int; using pointer = value_type *; using reference = value_type &; private: int d_value; public: OutputIterator(int init); // standard: bool operator==(OutputIterator const &other) const; bool operator!=(OutputIterator const &other) const; int &operator*(); OutputIterator &operator++(); // consider: int *operator->(); }; OutputIterator::OutputIterator(int init) : d_value(init) {} bool OutputIterator::operator!=(OutputIterator const &other) const { return d_value != other.d_value; } bool OutputIterator::operator==(OutputIterator const &other) const { return d_value == other.d_value; } OutputIterator &OutputIterator::operator++() { return *this; } int &OutputIterator::operator*() { return d_value; } c++-annotations-12.5.0/yo/concrete/examples/iterators/random.cc0000664000175000017500000000020514624637131023346 0ustar frankfrank#include "random.h" #include using namespace std; int main() { sort(RandomIterator{ 0 }, RandomIterator{ 100 }); } c++-annotations-12.5.0/yo/concrete/examples/iterators/forward.h0000664000175000017500000000210214624637127023377 0ustar frankfrank #include struct ForwardIterator { using iterator_category = std::forward_iterator_tag; using difference_type = std::ptrdiff_t; using value_type = int; using pointer = value_type *; using reference = value_type &; private: int d_value; public: ForwardIterator(int init); // standard: bool operator==(ForwardIterator const &other) const; bool operator!=(ForwardIterator const &other) const; int &operator*(); ForwardIterator &operator++(); // consider: int *operator->(); }; ForwardIterator::ForwardIterator(int init) : d_value(init) {} bool ForwardIterator::operator!=(ForwardIterator const &other) const { return d_value != other.d_value; } bool ForwardIterator::operator==(ForwardIterator const &other) const { return d_value == other.d_value; } ForwardIterator &ForwardIterator::operator++() { return *this; } int &ForwardIterator::operator*() { return d_value; } c++-annotations-12.5.0/yo/concrete/examples/noredir.cc0000664000175000017500000000077114624637131021524 0ustar frankfrank #include #include #include using namespace std; int main() { ofstream of("outfile"); streambuf *buf = cout.rdbuf(of.rdbuf()); cout << "To the of stream\n"; system("echo hello world"); cout << "To the of stream\n"; cout.rdbuf(buf); } /* Generated output: on the file `outfile' To the of stream To the of stream On standard output: hello world */ c++-annotations-12.5.0/yo/concrete/examples/foreachdemo.cc0000664000175000017500000000264614624637131022341 0ustar frankfrank#include #include #include #include "foreach.h" //VECTOR2 template class Vector2: public std::vector > { using iterator = typename Vector2::iterator; template friend Class &ForEach(Iterator begin, Iterator end, Class &object, void (Class::*member)(Data &)); public: void process(); private: void rows(std::vector &row); void columns(Type &str); }; template void Vector2::process() { ForEach, std::vector > (this->begin(), this->end(), *this, &Vector2::rows); } template void Vector2::rows(std::vector &row) { ForEach(row.begin(), row.end(), *this, &Vector2::columns); std::cout << '\n'; } template void Vector2::columns(Type &str) { std::cout << str << " "; } using namespace std; int main() { Vector2 c; c.push_back(vector(3, "Hello")); c.push_back(vector(2, "World")); c.process(); } /* Generated output: Hello Hello Hello World World */ //= c++-annotations-12.5.0/yo/concrete/examples/fistream/0000755000175000017500000000000014624637124021360 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/examples/fistream/fistream.ih0000664000175000017500000000020114624637127023512 0ustar frankfrank#include "fistream.h" // #include #include #include using namespace std; using namespace FBB; c++-annotations-12.5.0/yo/concrete/examples/fistream/fisin0000644000175000017500000000004514466730207022412 0ustar frankfrankba10 hello world My+name+is+%60Ed%27 c++-annotations-12.5.0/yo/concrete/examples/fistream/fistream.h0000664000175000017500000000337414624637127023357 0ustar frankfrank#ifndef INCLUDED_FISTREAM_H_ #define INCLUDED_FISTREAM_H_ #include #include #include #include #include /* fis >> field(3) >> x extracts x over max 3 positions. First, 3 chars are extracted from fis itself. They are put in a separate buffer which is then extracted. What if the extraction is not complete? Then a rest remains in the buffer, most likely resulting in a failing read, thereafter. Manipulators are provided to prevent this: field(0) returns to the non-fixed reading: the last field, even if not completely read, is then further ignored. field() reads the next field, same width as the previous field. If no field has been set before, field() has no effect. */ namespace FBB { class field; //INITIAL class Fistream: public std::istream { std::unique_ptr d_filebuf; std::streambuf *d_streambuf; std::istringstream d_iss; size_t d_width; //= public: //CONS Fistream(std::istream &stream); Fistream(char const *name, std::ios::openmode mode = std::ios::in); //= std::istream &setField(field const ¶ms); private: void setBuffer(); }; //FIELD class field { friend class Fistream; size_t d_width; bool d_newWidth; public: field(size_t width); field(); }; inline field::field(size_t width) : d_width(width), d_newWidth(true) {} inline field::field() : d_newWidth(false) {} //= } // FBB //OPEX namespace std { istream &operator>>(istream &str, FBB::field const ¶ms); } //= #endif c++-annotations-12.5.0/yo/concrete/examples/fistream/fistream.cc0000664000175000017500000000254114624637131023503 0ustar frankfrank#include "fistream.ih" //OPEX istream &std::operator>>(istream &str, field const ¶ms) { return static_cast(&str)->setField(params); } //= //CONS1 Fistream::Fistream(istream &stream) : istream(stream.rdbuf()), d_streambuf(rdbuf()), d_width(0) {} //= //CONS2 Fistream::Fistream(char const *name, ios::openmode mode) : istream(new filebuf()), d_filebuf(static_cast(rdbuf())), d_streambuf(d_filebuf.get()), d_width(0) { d_filebuf->open(name, mode); } //= //SETFIELD std::istream &Fistream::setField(field const ¶ms) { if (params.d_newWidth) // new field size requested d_width = params.d_width; // set new width if (!d_width) // no width? rdbuf(d_streambuf); // return to the old buffer else setBuffer(); // define the extraction buffer return *this; } //= //SETBUFFER void Fistream::setBuffer() { char *buffer = new char[d_width + 1]; rdbuf(d_streambuf); // use istream's buffer to buffer[read(buffer, d_width).gcount()] = 0; // read d_width chars, // terminated by a 0-byte d_iss.str(buffer); delete[] buffer; rdbuf(d_iss.rdbuf()); // switch buffers } //= c++-annotations-12.5.0/yo/concrete/examples/fistream/main.cc0000664000175000017500000000151514624637131022615 0ustar frankfrank#include #include "fistream.h" using namespace std; using namespace FBB; //MAIN int main() { Fistream fis(cin); fis >> hex; while (true) { size_t x; switch (x = fis.get()) { case '\n': cout << '\n'; break; case '+': cout << ' '; break; case '%': fis >> field(2) >> x >> field(0); // FALLING THROUGH default: cout << static_cast(x); break; case EOF: return 0; } } } /* Generated output after: echo My+name+is+%60Ed%27 | a.out My name is `Ed' */ //= c++-annotations-12.5.0/yo/concrete/examples/predicates.h0000664000175000017500000000566214624637127022060 0ustar frankfrank//UNARYPRED template class PredicateFunction1 { F_PTR d_fun; public: using argument_type = Type; PredicateFunction1(F_PTR const &ptr) : d_fun(ptr) {} bool operator()(Type const &t) const { return d_fun(t); } }; //= //BINPRED template class PredicateFunction2 { F_PTR d_fun; public: using first_argument_type = Type1; using second_argument_type = Type2; using result_type = bool; PredicateFunction2(F_PTR const &ptr) : d_fun(ptr) {} bool operator()(Type1 const &t1, Type2 const &t2) const { return d_fun(t1, t2); } }; //= //PREDOBJ1 template class PredicateObject1 { Class &d_cl; bool (Class::*d_member)(Type const &); public: using argument_type = Type; PredicateObject1(Class &cl, bool (Class::*member)(Type const &) = &Class::operator()) : d_cl(cl), d_member(member) {} PredicateObject1(Class *cl, bool (Class::*member)(Type const &) = &Class::operator()) : d_cl(*cl), d_member(member) {} bool operator()(Type const &t) const { return (d_cl.*d_member)(t); } operator Class() const { return d_cl; } }; //= //PREDOBJ2 template class PredicateObject2 { Class &d_cl; bool (Class::*d_member)(Type1 const &, Type2 const &); public: using first_argument_type = Type1; using second_argument_type = Type2; using result_type = bool; PredicateObject2(Class &cl, bool (Class::*member)(Type1 const &, Type2 const &) = &Class::operator()) : d_cl(cl), d_member(member) {} PredicateObject2(Class *cl, bool (Class::*member)(Type1 const &, Type2 const &) = &Class::operator()) : d_cl(*cl), d_member(member) {} bool operator()(Type1 const &t1, Type2 const &t2) const { return (d_cl.*d_member)(t1, t2); } operator Class() const { return d_cl; } }; //= c++-annotations-12.5.0/yo/concrete/examples/lines.cc0000664000175000017500000000101614624637131021165 0ustar frankfrank#include "lines.h" #include Lines::Lines(std::istream &in) { std::string str; while (getline(in, str)) d_line.push_back(str); } using namespace std; //MAIN int main() { ifstream in("lines.cc"); Lines lines(in); string s = lines[0]; // rvalue use lines[0] = s; // lvalue use cout << lines[0] << '\n'; // rvalue use lines[0] = "hello world"; // lvalue use cout << lines[0] << '\n'; // rvalue use } //= c++-annotations-12.5.0/yo/concrete/examples/parentslurp.cc0000664000175000017500000000117614624637131022441 0ustar frankfrank #include "parentslurp.h" #include #include //PARENT void ParentSlurp::parentProcess() { std::string line; size_t nr = 1; while (getline(std::cin, line)) std::cout << nr++ << ": " << line << '\n'; waitForChild(); } //= //MAIN int main() { ParentSlurp{}.fork(); } /* Generated Output (example only, actually obtained output may differ): 1: a.out 2: bitand.h 3: bitfunctional 4: bitnot.h 5: daemon.cc 6: fdinseek.cc 7: fdinseek.h ... */ //= c++-annotations-12.5.0/yo/concrete/examples/daemon.cc0000664000175000017500000000130514624637130021316 0ustar frankfrank #include #include #include "fork.h" class Daemon: public Fork { void parentProcess() override // the parent does nothing. {} void childProcess() override // actions by the child { sleep(3); // just a message... std::cout << "Hello from the child process\n"; throw 0; // The child process ends } }; int main() try { Daemon{}.fork(); } catch(...) {} /* Generated output: The next command prompt, then after 3 seconds: Hello from the child process */ c++-annotations-12.5.0/yo/concrete/examples/monitor/0000755000175000017500000000000014624637124021235 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/examples/monitor/monitor.h0000664000175000017500000000335514624637127023110 0ustar frankfrank #include #include #include #include "../selector.h" #include "child.h" //CLASS class Monitor { enum Commands { UNKNOWN, START, EXIT, STOP, TEXT, sizeofCommands }; using MapIntChild = std::map>; friend class Find; class Find { int d_nr; public: Find(int nr); bool operator()(MapIntChild::value_type &vt) const; }; Selector d_selector; int d_nr; MapIntChild d_child; static void (Monitor::*s_handler[])(int, std::string const &); static int s_initialize; public: enum Done {}; Monitor(); void run(); private: static void killChild(MapIntChild::value_type it); static int initialize(); Commands next(int *value, std::string *line); void processInput(); void processChild(int fd); void createNewChild(int, std::string const &); void exiting(int = 0, std::string const &msg = std::string{}); void sendChild(int value, std::string const &line); void stopChild(int value, std::string const &); void unknown(int, std::string const &); }; //= //CONS inline Monitor::Monitor() : d_nr(0) {} //= //FINDIMP inline Monitor::Find::Find(int nr) : d_nr(nr) {} inline bool Monitor::Find::operator()(MapIntChild::value_type &vt) const { return d_nr == vt.second->nr(); } //= c++-annotations-12.5.0/yo/concrete/examples/monitor/build0000755000175000017500000000017214466730207022262 0ustar frankfrank#!/bin/sh g++ --std=c++11 *.cc ../selector.cc ../fork.cc ../forkvirtual.cc \ ../pipe.cc -lbobcat -s c++-annotations-12.5.0/yo/concrete/examples/monitor/data.compiletime0000644000175000017500000000051014466730207024373 0ustar frankfrank #include "monitor.ih" //HANDLER void (Monitor::*Monitor::s_handler[])(int, string const &) = { &Monitor::unknown, // order follows enum Command's &Monitor::createNewChild, // elements &Monitor::exiting, &Monitor::stopChild, &Monitor::sendChild, }; //= c++-annotations-12.5.0/yo/concrete/examples/monitor/run.cc0000664000175000017500000000132314624637131022347 0ustar frankfrank #include "monitor.ih" int Monitor::s_initialize = Monitor::initialize(); void Monitor::run() { d_selector.addReadFd(STDIN_FILENO); while (true) { cout << "? " << flush; try { d_selector.wait(); int fd; while ((fd = d_selector.readFd()) != -1) { if (fd == STDIN_FILENO) processInput(); else processChild(fd); } cout << "NEXT ...\n"; } catch (char const *msg) { exiting(1, msg); } } } c++-annotations-12.5.0/yo/concrete/examples/monitor/child.h0000664000175000017500000000233614624637127022502 0ustar frankfrank #include "../pipe.h" #include "../fork.h" #include "../selector.h" #include #include #include #include //CLASS class Child: public Fork { Pipe d_in; Pipe d_out; int d_parentReadFd; int d_parentWriteFd; int d_nr; public: Child(int nr); ~Child() override; int readFd() const; int writeFd() const; int pid() const; int nr() const; private: void childRedirections() override; void parentRedirections() override; void childProcess() override; void parentProcess() override; }; //= //CONS inline Child::Child(int nr) : d_nr(nr) {} //= //PIPES inline int Child::readFd() const { return d_parentReadFd; } inline int Child::writeFd() const { return d_parentWriteFd; } //= //PIDNR inline int Child::pid() const { return Fork::pid(); } inline int Child::nr() const { return d_nr; } //= inline void Child::parentProcess() {} c++-annotations-12.5.0/yo/concrete/examples/monitor/monitor.cc0000664000175000017500000000175414624637131023242 0ustar frankfrank #include "monitor.ih" //KILL void Monitor::killChild(MapIntChild::value_type it) { if (kill(it.second->pid(), SIGTERM)) cerr << "Couldn't kill process " << it.second->pid() << '\n'; // reap defunct child process int status = 0; while( waitpid( it.second->pid(), &status, WNOHANG) > -1) ; } //= //EXIT void Monitor::exiting(int value, string const &msg) { for_each(d_child.begin(), d_child.end(), killChild); if (msg.length()) cerr << msg << '\n'; throw value; } //= //INIT void (Monitor::*Monitor::s_handler[sizeofCommands])(int, string const &); int Monitor::initialize() { s_handler[UNKNOWN] = &Monitor::unknown; s_handler[START] = &Monitor::createNewChild; s_handler[EXIT] = &Monitor::exiting; s_handler[STOP] = &Monitor::stopChild; s_handler[TEXT] = &Monitor::sendChild; return 0; } //= c++-annotations-12.5.0/yo/concrete/examples/monitor/processchild.cc0000664000175000017500000000041014624637131024221 0ustar frankfrank #include "monitor.ih" //CHILD void Monitor::processChild(int fd) { IFdStreambuf ifdbuf(fd); istream istr(&ifdbuf); string line; getline(istr, line); cout << d_child[fd]->pid() << ": " << line << '\n'; } //= c++-annotations-12.5.0/yo/concrete/examples/monitor/monitor.ih0000664000175000017500000000037714624637127023262 0ustar frankfrank #include "monitor.h" #include #include #include #include #include #include #include "../ifdbuf.h" #include "../fdout.h" using namespace std; c++-annotations-12.5.0/yo/concrete/examples/monitor/processinput.cc0000664000175000017500000000165614624637131024312 0ustar frankfrank #include "monitor.ih" //INPUT void Monitor::processInput() { string line; int value; Commands cmd = next(&value, &line); (this->*s_handler[cmd])(value, line); } //= //NEXT Monitor::Commands Monitor::next(int *value, string *line) { if (!getline(cin, *line)) exiting(1, "Monitor::next(): reading cin failed"); if (*line == "start") return START; if (*line == "exit" || *line == "quit") { *value = 0; return EXIT; } if (line->find("stop") == 0) { istringstream istr(line->substr(4)); istr >> *value; return !istr ? UNKNOWN : STOP; } istringstream istr(line->c_str()); istr >> *value; if (istr) { getline(istr, *line); return TEXT; } return UNKNOWN; } //= c++-annotations-12.5.0/yo/concrete/examples/monitor/sendchild.cc0000664000175000017500000000064214624637131023503 0ustar frankfrank #include "monitor.ih" //SEND void Monitor::sendChild(int nr, string const &line) { auto it = find_if(d_child.begin(), d_child.end(), Find(nr)); if (it == d_child.end()) cerr << "No child number " << nr << '\n'; else { OFdnStreambuf ofdn{ it->second->writeFd() }; ostream out(&ofdn); out << line << '\n'; } } //= c++-annotations-12.5.0/yo/concrete/examples/monitor/main.cc0000664000175000017500000000144414624637131022473 0ustar frankfrank #include "monitor.h" //MAIN int main() try { Monitor{}.run(); } catch (int exitValue) { return exitValue; } //= /* Example of a session: # a.out ? start Child 1 started ? 1 hello world ? 3394: Child 1:1: hello world ? 1 hi there! ? 3394: Child 1:2: hi there! ? start Child 2 started ? 3394: Child 1: standing by ? 3395: Child 2: standing by ? 3394: Child 1: standing by ? 3395: Child 2: standing by ? stop 1 ? 3395: Child 2: standing by ? 2 hello world ? 3395: Child 2:1: hello world ? 1 hello world No child number 1 ? exit3395: Child 2: standing by ? # */ c++-annotations-12.5.0/yo/concrete/examples/monitor/unknown.cc0000664000175000017500000000020714624637131023242 0ustar frankfrank #include "monitor.ih" void Monitor::unknown(int, string const &line) { cout << "unknown: " << line << "\n"; } c++-annotations-12.5.0/yo/concrete/examples/monitor/stopchild.cc0000664000175000017500000000057414624637131023543 0ustar frankfrank #include "monitor.ih" //STOP void Monitor::stopChild(int nr, string const &) { auto it = find_if(d_child.begin(), d_child.end(), Find{ nr }); if (it == d_child.end()) cerr << "No child number " << nr << '\n'; else { d_selector.rmReadFd(it->second->readFd()); d_child.erase(it); } } //= c++-annotations-12.5.0/yo/concrete/examples/monitor/child.cc0000664000175000017500000000275214624637131022635 0ustar frankfrank #include "child.h" #include #include #include using namespace std; //CHILD void Child::childRedirections() { d_in.readFrom(STDIN_FILENO); d_out.writtenBy(STDOUT_FILENO); } //= //PARENT void Child::parentRedirections() { d_parentReadFd = d_out.readOnly(); d_parentWriteFd = d_in.writeOnly(); } //= //PROCESS void Child::childProcess() { Selector selector; size_t message = 0; selector.addReadFd(STDIN_FILENO); selector.setAlarm(5); while (true) { try { if (!selector.wait()) // timeout cout << "Child " << d_nr << ": standing by\n"; else { string line; getline(cin, line); cout << "Child " << d_nr << ":" << ++message << ": " << line << '\n'; } } catch (...) { cout << "Child " << d_nr << ":" << ++message << ": " << "select() failed" << '\n'; } } exit(0); } //= //CHILDDES Child::~Child() { if (pid()) { cout << "Killing process " << pid() << "\n"; kill(pid(), SIGTERM); int status; wait(&status); } } //= c++-annotations-12.5.0/yo/concrete/examples/monitor/createnewchild.cc0000664000175000017500000000047414624637131024532 0ustar frankfrank #include "monitor.ih" //CHILD void Monitor::createNewChild(int, string const &) { Child *cp = new Child{ ++d_nr }; cp->fork(); int fd = cp->readFd(); d_selector.addReadFd(fd); d_child[fd].reset(cp); cerr << "Child " << d_nr << " started\n"; } //= c++-annotations-12.5.0/yo/concrete/examples/parentslurp.h0000664000175000017500000000134314624637127022304 0ustar frankfrank // compile with 'g++ parentslurp.cc fork.cc waitforchild.cc pipe.cc' #include "fork.h" #include "pipe.h" #include //CLASS class ParentSlurp: public Fork { Pipe d_pipe; void childRedirections() override; void parentRedirections() override; void childProcess() override; void parentProcess() override; }; //= //CHILDREDIR inline void ParentSlurp::childRedirections() { d_pipe.writtenBy(STDOUT_FILENO); } //= //PARENTREDIR inline void ParentSlurp::parentRedirections() { d_pipe.readFrom(STDIN_FILENO); } //= //CHILDPROC inline void ParentSlurp::childProcess() { execl("/bin/ls", "/bin/ls", 0); } //= c++-annotations-12.5.0/yo/concrete/examples/stringptrs/0000755000175000017500000000000014624637124021765 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/examples/stringptrs/stringptr.h0000664000175000017500000000221614624637127024200 0ustar frankfrank #ifndef INCLUDED_STRINGPTR_H_ #define INCLUDED_STRINGPTR_H_ #include #include #include "iterator.h" class StringPtr: public std::vector { public: using iterator = RandomPtrIterator < StringPtr, std::vector::iterator, std::string >; using reverse_iterator = std::reverse_iterator; iterator begin(); iterator end(); reverse_iterator rbegin(); reverse_iterator rend(); }; inline StringPtr::iterator StringPtr::begin() { return iterator(this->std::vector::begin() ); } inline StringPtr::iterator StringPtr::end() { return iterator(this->std::vector::end()); } inline StringPtr::reverse_iterator StringPtr::rbegin() { return reverse_iterator(end()); } inline StringPtr::reverse_iterator StringPtr::rend() { return reverse_iterator(begin()); } #endif c++-annotations-12.5.0/yo/concrete/examples/stringptrs/iterators.cc0000664000175000017500000000125314624637131024311 0ustar frankfrank#include #include #include "stringptr.h" using namespace std; int main(int argc, char **argv) { StringPtr sp; while (*argv) sp.push_back(new string{ *argv++ }); sort(sp.begin(), sp.end()); copy(sp.begin(), sp.end(), ostream_iterator(cout, " ")); cout << "\n======\n"; sort(sp.rbegin(), sp.rend()); copy(sp.begin(), sp.end(), ostream_iterator(cout, " ")); cout << '\n'; } /* when called as: a.out bravo mike charlie zulu quebec generated output: a.out bravo charlie mike quebec zulu ====== zulu quebec mike charlie bravo a.out */ c++-annotations-12.5.0/yo/concrete/examples/stringptrs/iterator.h0000664000175000017500000001140514624637127023775 0ustar frankfrank #ifndef INCLUDED_ITERATOR_H_ #define INCLUDED_ITERATOR_H_ //HEAD #include #include template struct RandomPtrIterator; #define PtrIterator RandomPtrIterator #define PtrIteratorValue RandomPtrIterator template bool operator==(PtrIterator const &lhs, PtrIterator const &rhs); template auto operator<=>(PtrIterator const &lhs, PtrIterator const &rhs); template int operator-(PtrIterator const &lhs, PtrIterator const &rhs); template struct RandomPtrIterator { using iterator_category = std::random_access_iterator_tag; using difference_type = std::ptrdiff_t; using value_type = Type; using pointer = value_type *; using reference = value_type &; friend PtrIterator Class::begin(); friend PtrIterator Class::end(); friend bool operator==<>(RandomPtrIterator const &lhs, RandomPtrIterator const &rhs); friend auto operator<=><>(RandomPtrIterator const &lhs, RandomPtrIterator const &rhs); friend int operator-<>(RandomPtrIterator const &lhs, RandomPtrIterator const &rhs); private: BaseIterator d_current; public: int operator-(RandomPtrIterator const &rhs) const; RandomPtrIterator operator+(int step) const; value_type &operator*() const; RandomPtrIterator &operator--(); RandomPtrIterator operator--(int); RandomPtrIterator &operator++(); RandomPtrIterator operator++(int); RandomPtrIterator operator-(int step) const; RandomPtrIterator &operator-=(int step); RandomPtrIterator &operator+=(int step); value_type *operator->() const; private: RandomPtrIterator(BaseIterator const ¤t); }; template PtrIteratorValue::RandomPtrIterator(BaseIterator const ¤t) : d_current(current) {} //= template PtrIteratorValue PtrIteratorValue::operator+(int step) const { return RandomPtrIterator(d_current + step); } //OP* template value_type &PtrIteratorValue::operator*() const { return **d_current; } //= //CMP template inline auto operator<=>(PtrIterator const &lhs, PtrIterator const &rhs) { return **lhs.d_current <=> **rhs.d_current; } //= template PtrIteratorValue &PtrIteratorValue::operator--() { --d_current; return *this; } template PtrIteratorValue PtrIteratorValue::operator--(int) { return RandomPtrIterator(d_current--); } //INC template PtrIteratorValue &PtrIteratorValue::operator++() { ++d_current; return *this; } template PtrIteratorValue PtrIteratorValue::operator++(int) { return RandomPtrIterator(d_current++); } //= template inline bool operator==(PtrIterator const &lhs, PtrIterator const &rhs) { return lhs.d_current == rhs.d_current; } template int operator-(PtrIterator const &lhs, PtrIterator const &rhs) { return lhs.d_current - rhs.d_current; } template PtrIteratorValue &PtrIteratorValue::operator-=(int step) { d_current -= step; return *this; } template PtrIteratorValue &PtrIteratorValue::operator+=(int step) { d_current += step; return *this; } template value_type *PtrIteratorValue::operator->() const { return *d_current; } #undef PtrIteratorValue #undef PtrIterator #endif c++-annotations-12.5.0/yo/concrete/examples/selector.h0000664000175000017500000000453614624637127021554 0ustar frankfrank #ifndef INCLUDED_SELECTOR_H_ #define INCLUDED_SELECTOR_H_ //HEADERS #include #include #include #include //= //CLASS class Selector { fd_set d_read; fd_set d_write; fd_set d_except; fd_set d_ret_read; fd_set d_ret_write; fd_set d_ret_except; timeval d_alarm; int d_max; int d_ret; int d_readidx; int d_writeidx; int d_exceptidx; public: Selector(); int exceptFd(); int nReady(); int readFd(); int wait(); int writeFd(); void addExceptFd(int fd); void addReadFd(int fd); void addWriteFd(int fd); void noAlarm(); void rmExceptFd(int fd); void rmReadFd(int fd); void rmWriteFd(int fd); void setAlarm(int sec, int usec = 0); private: int checkSet(int *index, fd_set &set); void addFd(fd_set *set, int fd); }; //= //NREADY inline int Selector::nReady() { return d_ret; } //= //READFD inline int Selector::readFd() { return checkSet(&d_readidx, d_ret_read); } //= inline int Selector::writeFd() { return checkSet(&d_writeidx, d_ret_write); } inline int Selector::exceptFd() { return checkSet(&d_exceptidx, d_ret_except); } //SETALARM inline void Selector::setAlarm(int sec, int usec) { d_alarm.tv_sec = sec; d_alarm.tv_usec = usec; } //= //NOALARM inline void Selector::noAlarm() { setAlarm(-1, -1); } //= //ADDREAD inline void Selector::addReadFd(int fd) { addFd(&d_read, fd); } //= inline void Selector::addWriteFd(int fd) { addFd(&d_write, fd); } inline void Selector::addExceptFd(int fd) { addFd(&d_except, fd); } //RMREAD inline void Selector::rmReadFd(int fd) { FD_CLR(fd, &d_read); } //= inline void Selector::rmWriteFd(int fd) { FD_CLR(fd, &d_write); } inline void Selector::rmExceptFd(int fd) { FD_CLR(fd, &d_except); } #endif c++-annotations-12.5.0/yo/concrete/examples/ifdbuf.h0000664000175000017500000000124714624637127021167 0ustar frankfrank #include #include //CLASS class IFdStreambuf: public std::streambuf { protected: int d_fd; char d_buffer[1]; public: IFdStreambuf(int fd); private: int underflow() override; }; //= //CONS inline IFdStreambuf::IFdStreambuf(int fd) : d_fd(fd) { setg(d_buffer, d_buffer + 1, d_buffer + 1); } //= //UFLOW inline int IFdStreambuf::underflow() { if (read(d_fd, d_buffer, 1) <= 0) return EOF; setg(d_buffer, d_buffer, d_buffer + 1); return static_cast(*gptr()); } //= c++-annotations-12.5.0/yo/concrete/examples/a2x.cc0000664000175000017500000000172114624637130020547 0ustar frankfrank#include #include "a2x.h" using namespace std; // compile with a2xis.cc int main() { //MAIN int x = A2x{ "12" }; // initialize int x from a string "12" A2x a2x{ "12.50" }; // explicitly create an A2x object double d; d = a2x; // assign a variable using an A2x object cout << d << '\n'; a2x = "err"; d = a2x; // d is 0: the conversion failed, cout << d << '\n'; // and a2x.good() == false a2x = " a"; // reassign a2x to new text char c = a2x; // c now 'a': internally operator>>() is used cout << c << '\n'; // so initial blanks are skipped. int expectsInt(int x); // initialize a parameter using an expectsInt(A2x{ "1200" }); // anonymous A2x object d = A2x{ "12.45" }.to(); // d is 12, not 12.45 cout << d << '\n'; //= } int expectsInt(int x) { cout << x << '\n'; return x; } c++-annotations-12.5.0/yo/concrete/examples/waitforchild.cc0000664000175000017500000000023714624637131022536 0ustar frankfrank #include "fork.ih" int Fork::waitForChild() { int status; waitpid(d_pid, &status, 0); return WEXITSTATUS(status); } c++-annotations-12.5.0/yo/concrete/examples/ifdbuf.cc0000664000175000017500000000035314624637131021315 0ustar frankfrank #include #include #include "ifdbuf.h" using namespace std; //MAIN int main() { IFdStreambuf fds(STDIN_FILENO); istream is(&fds); cout << is.rdbuf(); } //= c++-annotations-12.5.0/yo/concrete/examples/oformstream.h0000664000175000017500000000046714624637127022271 0ustar frankfrank #include class oformstream: public std::ostream // 1 { public: oformstream(std::ostream &ostr) // 2 : std::ostream(ostr.rdbuf()) {} std::ostream &form(char const *fmt, ...); // 3 }; c++-annotations-12.5.0/yo/concrete/examples/ifdnbuf.cc0000664000175000017500000000102614624637131021471 0ustar frankfrank #include #include #include #include "ifdnbuf.h" using namespace std; int main() { // internally: 30 char buffer IFdNStreambuf fds(STDIN_FILENO, 30); char buf[80]; // main() reads blocks of 80 // chars while (true) { size_t n = fds.sgetn(buf, 80); if (n == 0) break; cout.write(buf, n); } } c++-annotations-12.5.0/yo/concrete/examples/fdunget.h0000664000175000017500000000264014624637127021362 0ustar frankfrank #include #include #include #include #include //CLASS class FdUnget: public std::streambuf { int d_fd; size_t d_bufsize; size_t d_reserved; char *d_buffer; char *d_base; public: FdUnget(int fd, size_t bufsz, size_t unget); ~FdUnget() override; private: int underflow() override; }; //= //CONS FdUnget::FdUnget(int fd, size_t bufsz, size_t unget) : d_fd(fd), d_reserved(unget) { size_t allocate = bufsz > d_reserved ? bufsz : d_reserved + 1; d_buffer = new char[allocate]; d_base = d_buffer + d_reserved; setg(d_base, d_base, d_base); d_bufsize = allocate - d_reserved; } //= //DESTR inline FdUnget::~FdUnget() { delete[] d_buffer; } //= //UNDERFLOW int FdUnget::underflow() { size_t ungetsize = gptr() - eback(); size_t move = std::min(ungetsize, d_reserved); memcpy(d_base - move, egptr() - move, move); int nread = read(d_fd, d_base, d_bufsize); if (nread <= 0) // none read -> return EOF return EOF; setg(d_base - move, d_base, d_base + nread); return static_cast(*gptr()); } //= c++-annotations-12.5.0/yo/concrete/examples/for3.cc0000664000175000017500000000130014624637131020720 0ustar frankfrank #include #include #include #include "foreach.h" using namespace std; class StringVector: public vector { public: StringVector(char **begin, char **end) : vector(begin, end) {} void operator()(string const &str) { cout << str << " "; } }; int main(int argc, char **argv) { StringVector vs{ argv, argv + argc }; ForEach(vs.begin(), vs.end(), vs); cout << '\n'; } /* Output generated when running a.out alpha bravo charley a.out alpha bravo charley */ c++-annotations-12.5.0/yo/concrete/examples/ipipe.h0000664000175000017500000000072414624637127021035 0ustar frankfrank#ifndef INCLUDED_IPIPE_H_ #define INCLUDED_IPIPE_H_ #ifndef INCLUDED_PIPE_H_ #include "../pipe/pipe.h" #endif #ifndef INCLUDED_IFDSTREAMBUF_H_ #include "../ifdstreambuf/ifdstreambuf.h" #endif #ifndef SYSINC_ISTREAM_ #include #define SYSINC_ISTREAM_ #endif namespace FBB { class IPipe: public Pipe, private IFdStreambuf, public std::istream { public: IPipe(size_t size = 500); void closeWriteFd(); }; } #endif c++-annotations-12.5.0/yo/concrete/examples/bitfunctional0000644000175000017500000000327514466730207022341 0ustar frankfrank#ifndef BITFUNCTIONAL__ #define BITFUNCTIONAL__ #include /* Frank B. Brokken, july 19, 2001. f.b.brokken@rug.nl This file predefines function-objects that are non-standard. The following function objects are defined: name operator ---------------------------- shift_left << shift_right >> bit_not ~ bit_and & bit_or | bit_xor ^ ---------------------------- In order to make these objects available, install this file in a directory where your compiler finds it, and let sources do: #include This include directive implies #include */ template struct shift_left : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x << __y; } }; template struct shift_right : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x >> __y; } }; template struct bit_not : public unary_function<_Tp,_Tp> { _Tp operator()(const _Tp& __x) const { return ~__x; } }; template struct bit_and : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x & __y; } }; template struct bit_or : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x | __y; } }; template struct bit_xor : public binary_function<_Tp,_Tp,_Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x ^ __y; } }; #endif c++-annotations-12.5.0/yo/concrete/examples/forkvirtual.cc0000664000175000017500000000022614624637131022425 0ustar frankfrank #include "fork.ih" //REDIRECT void Fork::childRedirections() {} void Fork::parentRedirections() {} //= Fork::~Fork() {} c++-annotations-12.5.0/yo/concrete/examples/oformstream.cc0000664000175000017500000000144514624637131022417 0ustar frankfrank #include "oformstream.h" #include #include std::ostream &oformstream::form(char const *fmt, ...) // 1 { va_list list; va_start(list, fmt); size_t n = vsnprintf(0, 0, fmt, list); // 2 std::auto_ptr buf(new char[n + 1]); // 3 vsprintf(buf.get(), fmt, list); // 4 return *this << buf.get(); // 5 } using namespace std; int main() { oformstream of(cout); of << "Hello world\n"; cout << "Ok, "; of << "That's all, folks\n"; of.form("%s\n", "Hello world of C++") << '\n'; }; /* Generated output: Hello world Ok, That's all, folks Hello world of C++ */ c++-annotations-12.5.0/yo/concrete/examples/a2xis.cc0000664000175000017500000000035514624637130021105 0ustar frankfrank#include "a2x.h" A2x &A2x::operator=(char const *txt) { clear(); // very important!!! If a conversion failed, the object // remains useless until executing this statement str(txt); return *this; } c++-annotations-12.5.0/yo/concrete/examples/fork.cc0000664000175000017500000000072514624637131021022 0ustar frankfrank #include "fork.ih" void Fork::fork() { if ((d_pid = ::fork()) < 0) throw "Fork::fork() failed"; if (d_pid == 0) // childprocess has pid == 0 { childRedirections(); childProcess(); exit(1); // we shouldn't come here: } // childProcess() should exit parentRedirections(); parentProcess(); } c++-annotations-12.5.0/yo/concrete/examples/predobj.cc0000664000175000017500000000367414624637131021514 0ustar frankfrank #include #include #include #include #include "predicates.h" using namespace std; //CONTAINS class Contains { string d_target; size_t d_count; public: Contains(char const *target) : d_target(target), d_count(0) {} bool operator()(string const &str) { d_count++; return str.find_first_of(d_target) != string::npos; } bool operator()(string const &s1, string const &s2) { d_count++; return s1.find_first_of(s2) != string::npos; } size_t count() const { return d_count; } }; //= //MAIN int main(int argc, char **argv) { Contains contains{ "aeiou" }; if (argc == 1) cout << "Counted " << count_if(istream_iterator{ cin }, istream_iterator{}, PredicateObject1{contains} ) << " words containing vowels "; else cout << "Counted " << count_if(istream_iterator{ cin }, istream_iterator{}, [&](string const &target) { return PredicateObject2 { contains }(target, "aeiou"); } ) << " words containing vowels "; cout << "(read " << contains.count() << " strings)\n"; } /* Generated output after executing (predobj.cc being this soure file) a.out < predobj.cc or a.out 2 < predobj.cc Counted 107 words containing vowels (read 163 strings) */ //= c++-annotations-12.5.0/yo/concrete/examples/for2.cc0000664000175000017500000000133314624637131020725 0ustar frankfrank #include #include #include #include "foreach.h" using namespace std; class StringVector: public vector { public: StringVector(char **begin, char **end) : vector(begin, end) {} void display(string const &str) const { cout << str << " "; } }; int main(int argc, char **argv) { StringVector vs{ argv, argv + argc }; ForEach(vs.begin(), vs.end(), vs, &StringVector::display); cout << '\n'; } /* Output generated when running a.out alpha bravo charley a.out alpha bravo charley */ c++-annotations-12.5.0/yo/concrete/examples/fdinseek.cc0000664000175000017500000000132414624637130021644 0ustar frankfrank #include "fdinseek.h" #include #include #include #include using namespace std; int main() { IFdSeek fds(0); istream is(&fds); string s; while (true) { if (!getline(is, s)) break; streampos pos = is.tellg(); cout << setw(5) << pos << ": `" << s << "'\n"; if (!getline(is, s)) break; streampos pos2 = is.tellg(); cout << setw(5) << pos2 << ": `" << s << "'\n"; if (!is.seekg(pos)) { cout << "Seek failed\n"; break; } } } c++-annotations-12.5.0/yo/concrete/examples/selector.cc0000664000175000017500000000203514624637131021675 0ustar frankfrank #include "selector.h" //SELECTOR Selector::Selector() { FD_ZERO(&d_read); FD_ZERO(&d_write); FD_ZERO(&d_except); noAlarm(); d_max = 0; } //= //WAIT int Selector::wait() { timeval t = d_alarm; d_ret_read = d_read; d_ret_write = d_write; d_ret_except = d_except; d_readidx = 0; d_writeidx = 0; d_exceptidx = 0; d_ret = select(d_max, &d_ret_read, &d_ret_write, &d_ret_except, t.tv_sec == -1 && t.tv_usec == -1 ? 0 : &t); if (d_ret < 0) throw "Selector::wait()/select() failed"; return d_ret; } //= //ADDFD void Selector::addFd(fd_set *set, int fd) { FD_SET(fd, set); if (fd >= d_max) d_max = fd + 1; } //= //CHECKSET int Selector::checkSet(int *index, fd_set &set) { int &idx = *index; while (idx < d_max && !FD_ISSET(idx, &set)) ++idx; return idx == d_max ? -1 : idx++; } //= c++-annotations-12.5.0/yo/concrete/examples/fdinseek.h0000664000175000017500000000231314624637127021513 0ustar frankfrank #include "ifdbuf.h" #include #include //CLASS class IFdSeek: public IFdStreambuf { using pos_type = std::streambuf::pos_type; using off_type = std::streambuf::off_type; using seekdir = std::ios::seekdir; using openmode = std::ios::openmode; public: IFdSeek(int fd); private: pos_type seekoff(off_type offset, seekdir dir, openmode); pos_type seekpos(pos_type offset, openmode mode); }; //= //CONS inline IFdSeek::IFdSeek(int fd) : IFdStreambuf(fd) {} //= //SEEKOFF IFdSeek::pos_type IFdSeek::seekoff(off_type off, seekdir dir, openmode) { pos_type pos = lseek ( d_fd, off, (dir == std::ios::beg) ? SEEK_SET : (dir == std::ios::cur) ? SEEK_CUR : SEEK_END ); if (pos < 0) return -1; setg(d_buffer, d_buffer + 1, d_buffer + 1); return pos; } //= //SEEKPOS inline IFdSeek::pos_type IFdSeek::seekpos(pos_type off, openmode mode) { return seekoff(off, std::ios::beg, mode); } //= c++-annotations-12.5.0/yo/concrete/examples/pipe.h0000664000175000017500000000070114624637127020657 0ustar frankfrank#include //HEAD class Pipe { enum RW { READ, WRITE }; int d_fd[2]; //= public: Pipe(); int readOnly(); void readFrom(int fileDescriptor); int writeOnly(); void writtenBy(int fileDescriptor); void writtenBy(int const *fileDescriptors, size_t n = 2); private: void redirect(int d_fd, int alternateFd); }; c++-annotations-12.5.0/yo/concrete/a2x.yo0000644000175000017500000000673414466730207017005 0ustar frankfrank The standard bf(C) library offers conversion functions like ti(atoi), ti(atol), and other functions that can be used to convert NTB strings to numeric values. In bf(C++), these functions are still available, but a more em(type safe) way to convert text to other types uses objects of the class hi(istringstream)tt(std::istringsteam). Using the class tt(istringstream) instead of the bf(C) standard conversion functions may have the advantage of type-safety, but it also appears to be a rather cumbersome alternative. After all, we first have to construct and initialize a tt(std::istringstream) object before we're able to extract a value of some type from it. This requires us to use a variable. Then, in cases where the extracted value is only needed to initialize some function-parameter, one might wonder whether the added variable and the tt(istringstream) construction can somehow be avoided. In this section we'll develop a class hi(A2x)(tt(A2x)) preventing all the disadvantages of the standard bf(C) library functions, without requiring the cumbersome definitions of tt(istringstream) objects over and over again. The class is called tt(A2x), meaning hi(ascii to anything) `i(ascii to anything)'. tt(A2x) objects can be used to extract values of any type extractable from tt(std::istream) objects. Since tt(A2x) represents the object-variant of the bf(C) functions, it is not only type-safe but em(also) extensible. So its use is greatly preferred over using the standard bf(C) functions. Here are its characteristics: itemization( it() tt(A2x) is derived from tt(std::istringstream), and so all members of the class tt(istringstream) are available for tt(A2x) objects. Extractions of values of variables can always effortlessly be performed. Here's the class's interface: verbinclude(//CLASS examples/a2x.h) it() tt(A2x) has a default constructor and a constructor expecting a tt(std::string) argument. The latter constructor may be used to initialize tt(A2x) objects with text to be converted (e.g., a line of text obtained from reading a configuration file): verbinclude(//CONS examples/a2x.h) it() tt(A2x)'s real strength comes from its tt(operator Type()) conversion member template. As it is a member template, it automatically adapts itself to the type of the variable that should be given a value, obtained by converting the text stored inside the tt(A2x) object to the variable's type. When the extraction fails, tt(A2x)'s inherited tt(good) member returns tt(false). it() Occasionally the compiler may not be able to determine which type to convert to. In that case, an em(explicit template type) could be used: verb( A2x.operator int(); // or just: A2x.operator int();) As neither syntax looks attractive, the member template tt(to) is provided too, allowing constructions like: verb( A2x.to();) Here is its implementation: verbinclude(//TO examples/a2x.h) it() The tt(to) member makes it easy to implement tt(operator Type()): verbinclude(//TYPE examples/a2x.h) it() Once an tt(A2x) object is available, it may be reinitialized using tt(operator=): verbinclude(-a examples/a2xis.cc) ) Here are some examples showing tt(A2x) being used: verbinclude(//MAIN examples/a2x.cc) A complementary class hi(X2a) (tt(X2a)), converting values to text, can be constructed as well. Its construction is left as an exercise to the reader. c++-annotations-12.5.0/yo/concrete/fdinput.yo0000644000175000017500000000122414466730207017751 0ustar frankfrank When classes for input operation are derived from hi(streambuf)tt(std::streambuf), they should be provided with an input buffer of at least one character. The one-character input buffer allows for the use of the member functions tt(istream::putback) or tt(istream::ungetc). Strictly speaking it is not necessary to implement a buffer in classes derived from tt(streambuf). But using buffers in these classes is strongly advised. Their implementation is very simple and straightforward and the applicability of such classes is greatly improved. Therefore, all our classes derived from the class tt(streambuf) define a buffer of em(at least) one character. c++-annotations-12.5.0/yo/concrete/select.yo0000644000175000017500000000256014466730207017563 0ustar frankfrank The ti(select) system call was developed to handle asynchronous hi(multiplexing)emi(I/O multiplexing). The tt(select) system call is used to handle, e.g., input appearing simultaneously at a set of file descriptors. The tt(select) function is rather complex, and its full discussion is beyond the annotations()' scope. By encapsulating tt(select) in a tt(class Selector), hiding its details and offering an intuitively attractive interface, its use is simplified. The tt(Selector) class has these features: itemization( it() Efficiency. As most of tt(Select)'s members are very small, most members can be implemented inline. The class requires quite a few data members. Most of these data members belong to types that require some system headers to be included first: verbinclude(//HEADERS examples/selector.h) it() The class interface can now be defined. The data type tt(fd_set) is a type designed to be used by tt(select) and variables of this type contain the set of file descriptors on which tt(select) may sense some activity. Furthermore, tt(select) allows us to fire an emi(asynchronous alarm). To set the alarm time, the class tt(Selector) defines a ti(timeval) data member. Other members are used for internal bookkeeping purposes. Here is the class tt(Selector)'s interface: verbinclude(//CLASS examples/selector.h) ) c++-annotations-12.5.0/yo/concrete/oformstream.yo0000644000175000017500000000355614466730207020650 0ustar frankfrankIn the i(ANSI/ISO) standard does not include the previously available i(GNU) extension ti(form()) (and ti(scan())) for stream objects. In this section the construction of a class ti(oformstream) is described, which is derived from hi(derived class) ti(ostream) and does support tt(form()) and ti(vform()). Analogously to tt(oformstream) a tt(class) ti(iscanstream) can be developed, supporting tt(scan()) and ti(vscan()). The contruction of this latter class is left as an i(exercise) to the reader. Here is the class interface and definition. It is annotated below: verbinclude(-a examples/oformstream.h) itemization( it() At 1 the class is defined: it is derived from tt(ostream), so it inherits tt(ostream)'s capabilities. it() At 2 a simple constructor is defined. It expects a reference to a tt(std::ostream) object. it() At 3 the member tt(form()) is declared. Its definition is given shortly. ) A program using the class tt(oformstream) is given in the next example. It prints a well-known string and some marker text: verbinclude(-a examples/oformstream.cc) In the above example: itemization( it() At 1 the function tt(form()) is defined. it() At 2 the function ti(vsnprintf()) is given a buffer size of 0 and tt(0) as the pointer to the buffer. According to the ti(ISO/IEC 9899:1999) standard, the function tt(vsnprintf()) returns the number of required characters for the formatted string (not including the final 0-valued character) (see the tt(vsnprintf()) man page for details and possible alternative implementations of tt(vsnprintf())). it() At 3 an ti(auto_ptr) is used to manage the dynamically hi(dynamic allocation) allocated buffer. it() At 4 the text is formatted. it() At 5 the content of the buffer are written to the tt(ostream) base class, and the tt(oformstream) object is returned. ) c++-annotations-12.5.0/yo/concrete/insertion.yo0000644000175000017500000000400414466730207020311 0ustar frankfrankClasses also frequently define overloaded insertion and extraction operators. Since there are no `compound insertion operators' the design shown so far cannot be used when overloading these operators. Instead using standardized member function signatures is advocated: tt(void insert(std::ostream &out) const) to insert an object into an tt(ostream) and tt(void extract(std::istream &in) const) to extract an object from an tt(istream). As these functions are only used by, respectively, the insertion and extraction operators, they can be declared in the tt(Derived) class's private interface. Instead of declaring the insertion and extraction operators friends of the class tt(Derived) a single tt(friend Binops) is specified. This allows tt(Binops) to define private, inline tt(iWrap) and tt(eWrap) members, merely calling, respectively, tt(Derived's insert) and tt(extract) members: verb( template inline void Binops::iWrap(std::ostream &out) const { static_cast(*this).insert(out); }) tt(Binops) then declares the insertion and extraction operators as its friends, allowing these operators to call, respectively, tt(iWrap) and tt(eWrap). Note that the software engineer designing the class tt(Derived) only has to provide a tt(friend Binops) declaration. Here is the implementation of the overloaded insertion operator: verb( template std::ostream &operator<<(std::ostream &out, Binops const &obj) { obj.iWrap(out); return out; }) This completes the coverage of the essentials of a class template tt(Binops) potentially offering binary operators and insertion/extraction operators for any class derived from tt(Binops). Finally, as noted at the beginning of this section, a complete implementation of a class offering addition and insertion operators is provided in the file tt(annotations/yo/concrete/examples/binopclasses.cc) in the annotations()' source archive. c++-annotations-12.5.0/yo/concrete/parserh.yo0000644000175000017500000000117414466730207017750 0ustar frankfrankSeveral class members called from the grammar are defined as member templates. tt(Bisonc++) generates multiple files, among which the file defining the parser's class. Functions called from the production rule's action blocks are usually member functions of the parser. These member functions must be declared and defined. Once tt(bisonc++) has generated the header file defining the parser's class, that header file isn't automatically rewritten, allowing the programmer to add new members to the parser class whenever required. Here is `tt(parser.h)' as used in our little calculator: verbinclude(-a bisonc++/parser/parser.h) c++-annotations-12.5.0/yo/concrete/streambuf/0000755000175000017500000000000014466730207017720 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/0000755000175000017500000000000014624637124022222 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/fdin2cout.cc0000664000175000017500000000055714624637131024435 0ustar frankfrank#include "fdstreambuf.h" #include #include #include using namespace std; // Calls uflow() repeatedly int main(int argc) { fdstreambuf fds(0, ios::in); istream is(&fds); cout << "START\n"; char c; while (is.get(c)) cout << "GOT " << c << '\n'; cout << "Using fds(0)\n"; } c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/fdinrdbuf.cc0000664000175000017500000000057014624637131024476 0ustar frankfrank#include "inok/buf.1.h" #include #include #include using namespace std; // Calls uflow() repeatedly int main(int argc) { fdstreambuf fds(0, ios::in); istream is(&fds); cout << "START\n"; cout << &fds;//is.rdbuf(); cout.clear(); // because of cerr.eof() cout << "Using fds(0)\n"; } c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/fdinbuf100.cc0000664000175000017500000000077014624637131024373 0ustar frankfrank#include "fdstreambuf.h" #include #include #include using namespace std; int main(int argc) { fdstreambuf fds(0, 5, ios::in); istream is(&fds); string s; cout << "START\n"; for (size_t line = 0; getline(is, s); line++) { cout << s << '\n'; if ((line & 3) == 0) { is.unget(); is.unget(); is.unget(); is.unget(); } is.clear(); } } c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/fdstreambuf.h0000664000175000017500000000403514624637127024704 0ustar frankfrank#include #include #include #include using namespace std; class fdstreambuf: public std::streambuf { public: fdstreambuf(int fd, size_t bufsize, size_t minimum, std::ios::openmode mode = std::ios::in | std::ios::out) : fd(fd), bufsize(bufsize), minimum(minimum), buffer(new char[bufsize]) { /* initialize buffer from minimum position to beyond, set gptr() to beyond, so the buffer is filled immediately Assume bufsize - minimum > minimum */ if (mode & std::ios::in) setg(buffer + minimum, buffer + bufsize, buffer + bufsize); } ~fdstreambuf() { delete buffer; } int underflow() // inspects the character { if (gptr() < egptr()) return static_cast(*gptr()); // return next char waiting in the buffer /* Now that the buffer is refilled, what do we have? buffer eback() gptr() == egptr() ^ ^ ^ ------------------------------- n m <= bufsize - minimum n characters at chars before gptr() are moved left, eback() is moved left over n filling starts are buffer + minimum */ size_t n2move = min(minimum, (size_t)(gptr() - eback())); memcpy(buffer, egptr() - n2move, n2move); /* Read chars to the area beyond the unget-buffer */ int nread = read(fd, buffer + minimum, bufsize - minimum); if (nread <= 0) // none read -> return EOF; setg(buffer + minimum - n2move, buffer + minimum, buffer + minimum + nread); return static_cast(*gptr()); } private: int fd; size_t bufsize; size_t minimum; char* buffer; }; c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/input0000644000175000017500000000000714466730207023301 0ustar frankfranks a a c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/fdinmininum.cc0000664000175000017500000000074514624637131025054 0ustar frankfrank#include "inok/minimum.h" #include #include #include using namespace std; int main(int argc) { fdstreambuf fds(0, 12, 5, ios::in); istream is(&fds); string s; for (size_t line = 0; getline(is, s); line++) { cout << s << '\n'; if ((line & 3) == 0) { is.unget(); is.unget(); is.unget(); is.unget(); } is.clear(); } } c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/fdinextracttocout.cc0000664000175000017500000000056114624637131026304 0ustar frankfrank#include "inok/buf.1.h" #include #include #include using namespace std; // Calls uflow() repeatedly int main(int argc) { fdstreambuf fds(0, ios::in); istream is(&fds); cerr << "START\n"; char c; while (is >> c) cerr << "\t\tGOT " << c << '\n'; cerr << "Using fds(0)\n"; } c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/fdinputback.cc0000664000175000017500000000050614624637131025024 0ustar frankfrank#include "inok/buf.1.h" #include #include #include using namespace std; int main(int argc) { fdstreambuf fds(0, ios::in); istream is(&fds); cout << "START\n"; char c; is.get(c); cout << c << '\n'; is.unget(); cout << is.rdbuf(); } c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/fbinbufn.cc0000664000175000017500000000077014624637131024326 0ustar frankfrank#include "fdstreambuf.h" #include #include #include using namespace std; int main(int argc) { fdstreambuf fds(0, 5, ios::in); istream is(&fds); string s; cout << "START\n"; for (size_t line = 0; getline(is, s); line++) { cout << s << '\n'; if ((line & 3) == 0) { is.unget(); is.unget(); is.unget(); is.unget(); } is.clear(); } } c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/fdstreambuf.h00000644000175000017500000000324414466730207024760 0ustar frankfrank#include #include #include #include using std::cerr; class fdstreambuf: public std::streambuf { public: fdstreambuf(int fd, std::ios::openmode mode = std::ios::in | std::ios::out) : fd(fd), input_char(EOF), mode(mode) { std::streambuf::_M_mode = mode; // char // dummy; // if (mode & std::ios::in) // setg(&dummy, &dummy, &dummy); // if (mode & std::ios::out) // setp(&dummy, &dummy); } int uflow() // consumes the character { std::cerr << "uflow\n"; if (input_char != EOF) { int next = input_char; input_char = EOF; return next; } return underflow(); } int underflow() // inspects the character { std::cerr << "underflow, in_avail() = " << in_avail() << "\n"; char c; if (read(fd, &c, 1)) { // std::cerr << "Got " << c; input_char = c; std::cerr << ", input_char is " << input_char << " (" << (char)input_char << ")\n"; return input_char; } //std::cerr << "EOF underflow\n"; return input_char = EOF; } int overflow(int c) { if (c != EOF) { if (write(fd, &c, 1) != 1) return EOF; } return c; } private: std::ios::openmode mode; int fd, input_char; }; c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/inok/0000755000175000017500000000000014624637123023161 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/inok/seek.1.h0000664000175000017500000000333314624637127024430 0ustar frankfrank#include #include #include #include #include #include using namespace std; class fdstreambuf: public std::streambuf { public: fdstreambuf(int fd, std::ios::openmode mode = std::ios::in | std::ios::out) : fd(fd) { if (mode & std::ios::in) setg(buffer, buffer + 1, buffer + 1); } pos_type seekoff(off_type offset, ios::seekdir dir, ios_base::openmode) { pos_type pos = lseek ( fd, offset, (dir == ios::beg) ? SEEK_SET : (dir == ios::cur) ? SEEK_CUR : SEEK_END ); if (pos < 0) return -1; setg(buffer, buffer + 1, buffer + 1); return pos; } pos_type // used by seekg() seekpos(pos_type offset, ios_base::openmode mode) { return seekoff(offset, ios::beg, mode); } int underflow() // inspects the character { if (gptr() < egptr()) return static_cast(*gptr()); // return next char waiting in the buffer if (read(fd, buffer, 1) <= 0) // none read -> return EOF; setg(buffer, buffer, buffer + 1); return static_cast(*gptr()); } private: char buffer[1]; int fd; }; c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/inok/buf.n.h0000664000175000017500000000216514624637127024354 0ustar frankfrank#include #include #include class fdstreambuf: public std::streambuf { public: fdstreambuf(int fd, size_t bufsize, std::ios::openmode mode = std::ios::in | std::ios::out) : fd(fd), bufsize(bufsize), buffer(new char[bufsize]) { if (mode & std::ios::in) setg(buffer, buffer + bufsize, buffer + bufsize); } ~fdstreambuf() { delete buffer; } int underflow() // inspects the character { if (gptr() < egptr()) return static_cast(*gptr()); // return next char waiting in the buffer int nread = read(fd, buffer, bufsize); if (nread <= 0) // none read -> return EOF; setg(buffer, buffer, buffer + nread); return static_cast(*gptr()); } private: int fd; size_t bufsize; char* buffer; }; c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/inok/minimum.h0000664000175000017500000000403514624637127025015 0ustar frankfrank#include #include #include #include using namespace std; class fdstreambuf: public std::streambuf { public: fdstreambuf(int fd, size_t bufsize, size_t minimum, std::ios::openmode mode = std::ios::in | std::ios::out) : fd(fd), bufsize(bufsize), minimum(minimum), buffer(new char[bufsize]) { /* initialize buffer from minimum position to beyond, set gptr() to beyond, so the buffer is filled immediately Assume bufsize - minimum > minimum */ if (mode & std::ios::in) setg(buffer + minimum, buffer + bufsize, buffer + bufsize); } ~fdstreambuf() { delete buffer; } int underflow() // inspects the character { if (gptr() < egptr()) return static_cast(*gptr()); // return next char waiting in the buffer /* Now that the buffer is refilled, what do we have? buffer eback() gptr() == egptr() ^ ^ ^ ------------------------------- n m <= bufsize - minimum n characters at chars before gptr() are moved left, eback() is moved left over n filling starts are buffer + minimum */ size_t n2move = min(minimum, (size_t)(gptr() - eback())); memcpy(buffer, egptr() - n2move, n2move); /* Read chars to the area beyond the unget-buffer */ int nread = read(fd, buffer + minimum, bufsize - minimum); if (nread <= 0) // none read -> return EOF; setg(buffer + minimum - n2move, buffer + minimum, buffer + minimum + nread); return static_cast(*gptr()); } private: int fd; size_t bufsize; size_t minimum; char* buffer; }; c++-annotations-12.5.0/yo/concrete/streambuf/fdstreambuf/fdinseek.cc0000664000175000017500000000131214624637131024316 0ustar frankfrank#include "fdstreambuf.h" #include #include #include #include using namespace std; int main(int argc) { fdstreambuf fds(0, ios::in); istream is(&fds); string s; cout << "START\n"; while (true) { if (!getline(is, s)) break; streampos pos = is.tellg(); cout << setw(5) << pos << ": `" << s << "'\n"; if (!getline(is, s)) break; streampos pos2 = is.tellg(); cout << setw(5) << pos2 << ": `" << s << "'\n"; if (!is.seekg(pos)) { cout << "Seek failed\n"; return 1; } } } c++-annotations-12.5.0/yo/concrete/poly/0000755000175000017500000000000014624637124016713 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/poly/input0000644000175000017500000000002514466730207017772 0ustar frankfrankabc(def); xyz = 5; c++-annotations-12.5.0/yo/concrete/poly/semantic/0000755000175000017500000000000014624637123020515 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/poly/semantic/semantic.h0000664000175000017500000000111714624637127022477 0ustar frankfrank#ifndef INCLUDED_SEMANTIC_ #define INCLUDED_SEMANTIC_ #include #include #include "../base/base.h" class Semantic: public std::shared_ptr { friend std::ostream &operator<<(std::ostream &out, Semantic const &obj); public: Semantic(Base *bp = 0); // Semantic owns the bp ~Semantic() = default; }; inline Semantic::Semantic(Base *bp) : std::shared_ptr(bp) {} inline std::ostream &operator<<(std::ostream &out, Semantic const &obj) { if (obj) return out << *obj; return out << ""; } #endif c++-annotations-12.5.0/yo/concrete/poly/parser/0000755000175000017500000000000014624637123020206 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/poly/parser/parser.h0000664000175000017500000000202014624637127021653 0ustar frankfrank#ifndef Parser_h_included #define Parser_h_included // $insert baseclass #include "parserbase.h" // $insert scanner.h #include "../scanner/scanner.h" #undef Parser class Parser: public ParserBase { // $insert scannerobject Scanner d_scanner; public: Parser(); int parse(); private: void error(char const *msg); // called on (syntax) errors int lex(); // returns the next token from the // lexical scanner. void print(); // use, e.g., d_token, d_loc // support functions for parse(): void executeAction(int ruleNr); void errorRecovery(); int lookup(bool recovery); void nextToken(); }; inline void Parser::error(char const *msg) { std::cerr << msg << '\n'; } // $insert lex inline int Parser::lex() { return d_scanner.yylex(); } inline void Parser::print() // use d_token, d_loc {} inline Parser::Parser() : d_scanner(&d_val__) {} #endif c++-annotations-12.5.0/yo/concrete/poly/parser/parser.ih0000664000175000017500000000017314624637127022033 0ustar frankfrank // Include this file in the sources of the class Parser. // $insert class.h #include "parser.h" using namespace std; c++-annotations-12.5.0/yo/concrete/poly/parser/grammar0000644000175000017500000000054614466730207021565 0ustar frankfrank%filenames parser %scanner ../scanner/scanner.h %baseclass-preinclude preinclude.h %stype Semantic %token INT IDENTIFIER %% rules: rules rule | rule ; rule: IDENTIFIER '(' IDENTIFIER ')' ';' { cout << $1 << " " << $3 << '\n'; } | IDENTIFIER '=' INT ';' { cout << $1 << " " << $3 << '\n'; } ; c++-annotations-12.5.0/yo/concrete/poly/parser/preinclude.h0000664000175000017500000000023414624637127022516 0ustar frankfrank#ifndef INCLUDED_PREINCLUDE_H_ #define INCLUDED_PREINCLUDE_H_ #include "../int/int.h" #include "../text/text.h" #include "../semantic/semantic.h" #endif c++-annotations-12.5.0/yo/concrete/poly/scanner/0000755000175000017500000000000014624637123020343 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/poly/scanner/scanner.ih0000664000175000017500000000175614624637127022335 0ustar frankfrank/* Declare here what's only used in the Scanner class and let Scanner's sources include "scanner.ih" */ #include "scanner.h" //#include // #include // #include // #include /* In the current Debian distribution of flex, YY_CURRENT_BUFFER and YY_START are not available to members of the flex-generated class (See `Values Available To The User' in the flex info-file). Use the following macros to make these values available. (Note that the need for these defines may be superfluous in the near future): */ // uncomment if you want to use YY_CURRENT_BUFFER in the scanner's members: /* #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) */ // uncomment if you want to use YY_START in the scanner's members: // #define YY_START (((yy_start) - 1) / 2) // end of scanner.ih c++-annotations-12.5.0/yo/concrete/poly/scanner/scanner.h0000664000175000017500000000062714624637127022160 0ustar frankfrank#ifndef SCANNER_H_ #define SCANNER_H_ #include "../semantic/semantic.h" #if ! defined(SKIP_FLEXLEXER_) && ! defined(SYSINC_FLEXLEXER_H_) #include #define SYSINC_FLEXLEXER_H_ #endif class Scanner: public yyFlexLexer { Semantic *d_semval; public: Scanner(Semantic *semval); int yylex(); }; inline Scanner::Scanner(Semantic *semval) : d_semval(semval) {} #endif c++-annotations-12.5.0/yo/concrete/poly/scanner/lexer0000644000175000017500000000117314466730207021410 0ustar frankfrank%{ #define SKIP_FLEXLEXER_ #include "scanner.ih" #include "../parser/preinclude.h" #include "../parser/parserbase.h" %} %option yyclass="Scanner" outfile="yylex.cc" %option c++ 8bit warn noyywrap yylineno %option debug %% [ \t]+ // Often used: skip white space \n // same [0-9]+ { d_semval->reset(new Int(yytext)); return Parser::INT; } [a-zA-Z_][a-zA-Z0-9_]* { d_semval->reset(new Text(yytext)); return Parser::IDENTIFIER; } . return yytext[0]; %% c++-annotations-12.5.0/yo/concrete/poly/base/0000755000175000017500000000000014624637124017625 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/poly/base/base.ih0000664000175000017500000000005014624637127021061 0ustar frankfrank#include "base.h" using namespace std; c++-annotations-12.5.0/yo/concrete/poly/base/clone.cc0000664000175000017500000000011114624637131021225 0ustar frankfrank#include "base.ih" Base *Base::clone() const { return ownClone(); } c++-annotations-12.5.0/yo/concrete/poly/base/base.h0000664000175000017500000000103014624637127020707 0ustar frankfrank #ifndef INCLUDED_BASE_ #define INCLUDED_BASE_ #include class Base { friend std::ostream &operator<<(std::ostream &out, Base const &obj); public: virtual ~Base() = default; Base *clone() const; private: virtual Base *ownClone() const = 0; virtual std::ostream &insert(std::ostream &os) const = 0; }; inline std::ostream &operator<<(std::ostream &out, Base const &obj) { return obj.insert(out); } #endif c++-annotations-12.5.0/yo/concrete/poly/icmconf0000644000175000017500000000675014466730207020264 0ustar frankfrank // Inspect the following #defines. Change them to taste. If you don't // need a particular option, change its value into an empty string // should commands be echoed (ON) or not (OFF) ? #define USE_ECHO ON // The final program and source containing main(): // =============================================== // define the name of the program to create: #define BINARY "../../poly" // define the name of the source containing main(): #define MAIN "main.cc" // #defines used for compilation and linking: // ========================================== // define the compiler to use: #define COMPILER "g++" // define the compiler options to use: #define COMPILER_OPTIONS "-g --std=c++0x -Wall -O2" // define the pattern to locate sources in a directory: #define SOURCES "*.cc" // define the options used for linking: #define LINKER_OPTIONS "-s" // define any additional libraries BINARY may need: #define ADD_LIBRARIES "bobcat" // define any additional paths (other than the standard paths) the // additional libraries are located in: #define ADD_LIBRARY_PATHS "" // #defines used for the final product: // ==================================== #define BIN_INSTALL "/usr/local/bin" // Some advanced #defines, used to create parsers and lexical scanners // =================================================================== // Lexical Scanner section // ======================= // Should a lexical scanner be constructed? If so, define the subdirectory // containing the scanner's specification file. #define SCANNER_DIR "scanner" // What is the program generating the lexical scanner? #define SCANGEN "flex" // Flags to provide SCANGEN with: #define SCANFLAGS "-I" // Name of the lexical scanner specification file #define SCANSPEC "lexer" // Name of the file generated by the lexical scanner #define SCANOUT "yylex.cc" // Parser section // ============== // Should a parser be constructed? If so, define the subdirectory // containing the parser's specification file #define PARSER_DIR "parser" // If a parser must be constructed, should the script (provided in the // skeleton file parser/gramspec/grambuild) `parser/gramspec/grambuild' // **NOT** be called? If it must NOT be called, comment out the following // #define directive: // #define GRAMBUILD // What it the program generating a parser? #define PARSGEN "bisonc++" // What it the grammar specificication file? #define PARSSPEC "grammar" // Flags to provide PARSGEN with: #define PARSFLAGS "-V -l" // Name of the file generated by the parser generator containing the // parser function #define PARSOUT "parse.cc" // Additional defines, which should normally not be modified // ========================================================= // Directory below this directory to contain temporary results #define TMP_DIR "tmp" // Local program library to use (change to an empty string if you want to // use the object modules themselves, rather than a library) #define LIBRARY "modules" // The extension of object modules: #define OBJ_EXT ".o" // below #define DEFCOM "program" or "library" may be added by icmstart #define DEFCOM "program" c++-annotations-12.5.0/yo/concrete/poly/main.cc0000664000175000017500000000020114624637131020137 0ustar frankfrank#include "main.ih" int main(int argc, char **argv) { Parser parser; parser.setDebug(argc == 1); parser.parse(); } c++-annotations-12.5.0/yo/concrete/poly/main.ih0000664000175000017500000000016314624637127020166 0ustar frankfrank#include #include #include #include "parser/preinclude.h" #include "parser/parser.h" c++-annotations-12.5.0/yo/concrete/poly/int/0000755000175000017500000000000014624637123017504 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/poly/int/int.h0000664000175000017500000000134414624637127020457 0ustar frankfrank#ifndef INCLUDED_INT_ #define INCLUDED_INT_ #include #include #include "../base/base.h" class Int: public Base { int d_value; public: Int(char const *text); Int(int v); int value() const; // directly access the value private: virtual Base *ownClone() const; virtual std::ostream &insert(std::ostream &os) const; }; inline Int::Int(char const *txt) : d_value(FBB::A2x(txt)) {} inline Int::Int(int v) : d_value(v) {} inline Base *Int::ownClone() const { return new Int(*this); } inline int Int::value() const { return d_value; } inline std::ostream &Int::insert(std::ostream &out) const { return out << d_value; } #endif c++-annotations-12.5.0/yo/concrete/poly/text/0000755000175000017500000000000014624637123017676 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/poly/text/text.h0000664000175000017500000000126114624637127021041 0ustar frankfrank#ifndef INCLUDED_TEXT_ #define INCLUDED_TEXT_ #include #include #include "../base/base.h" class Text: public Base { std::string d_text; public: Text(char const *id); std::string const &id() const; // directly access the name. private: virtual Base *ownClone() const; virtual std::ostream &insert(std::ostream &os) const; }; inline Text::Text(char const *id) : d_text(id) {} inline Base *Text::ownClone() const { return new Text(*this); } inline std::string const &Text::id() const { return d_text; } inline std::ostream &Text::insert(std::ostream &out) const { return out << d_text; } #endif c++-annotations-12.5.0/yo/concrete/fdout.yo0000644000175000017500000001424614466730207017431 0ustar frankfrank Reading and writing from and to em(file descriptors)hi(file descriptor) are not part of the bf(C++) standard. But on most operating systems file descriptors em(are) available and can be considered a i(device). It seems natural to use the class hi(streambuf)tt(std::streambuf) as the starting point for constructing classes interfacing such file descriptor devices. Below we'll construct classes that can be used to write to a device given its file descriptor. The devices may be files, but they could also be i(pipe)s or i(socket)s. Section ref(STRBUF) covers reading from such devices; section ref(REDIRECTION) reconsiders redirection, discussed earlier in section ref(REDIR). Using the tt(streambuf) class as a base class it is relatively easy to design classes for output operations. The only member function that em(must) be overridden is the (virtual) member hi(overflow) tt(int streambuf::overflow(int c)). This member's responsibility is to write characters to the device. If tt(fd) is an output file descriptor and if output should not be buffered then the member tt(overflow()) can simply be implemented as: verb( class UnbufferedFD: public std::streambuf { public: int overflow(int c) override; ... }; int UnbufferedFD::overflow(int c) { if (c != EOF) { if (write(d_fd, &c, 1) != 1) return EOF; } return c; }) The argument received by tt(overflow) is either written to the file descriptor (and returned from tt(overflow)), or endOfFile() is returned. This simple function does not use output buffering. For various reasons, using a buffer is usually a good idea (see also the next section). When output buffering is used, the tt(overflow) member is a bit more complex as it is only called when the buffer is full. Once the buffer is full, we em(first) have to flush the buffer. Flushing the buffer is the responsibility of the (virtual) function hi(sync)tt(streambuf::sync). Since tt(sync) is a virtual function, classes derived from tt(streambuf) may redefine tt(sync) to flush a buffer tt(streambuf) itself doesn't know about. Overriding tt(sync) and using it in tt(overflow) is not all that has to be done. When the object of the class defining the buffer reaches the end of its lifetime the buffer may be only partially full. In that situation the buffer must also be flushed. This is easily done by simply calling tt(sync) from the class's destructor. Now that we've considered the consequences of using an output buffer, we're almost ready to design our derived class. Several more features are added as well, though: itemization( it() First, we should allow the user of the class to specify the size of the output buffer. it() Second, it should be possible to construct an object of our class before the file descriptor is actually known. Later, in section ref(FORK) we'll encounter a situation where this feature is actually used. ) To save some space in the annotations(), the successful completion of the functions designed here is not checked in the example code. In `real life' implementations these checks should of course not be omitted. Our class tt(OFdnStreambuf) has the following characteristics: itemization( it() Its member functions use low-level functions operating on file descriptors. So apart from tt(streambuf) the tthi(unistd.h) header file must have been read by the compiler before its member functions can be compiled. it() The class is derived from tt(std::streambuf). it() It defines three data members. These data members keep track of, respectively, the size of the buffer, the file descriptor, and the buffer itself. Here is the full class interface verbinclude(//CLASS examples/fdout.h) it() Its default constructor merely initializes the buffer to 0. Slightly more interesting is its constructor expecting a file descriptor and a buffer size. This constructor passes its arguments on to the class's tt(open) member (see below). Here are the constructors: verbinclude(//CONS examples/fdout.h) it() The destructor calls tt(sync), flushing any characters stored in the output buffer to the device. In implementations not using a buffer the destructor can be given a default implementation: verbinclude(//DESTR examples/fdout.h) This implementation does not close the device. It is left as an exercise to the reader to change this class in such a way that the device is optionally closed (or optionally remains open). This approach was adopted by, e.g., the url(Bobcat library)(http://fbb-git.gitlab.io/bobcat/). hi(Bobcat library)hi(http://fbb-git.gitlab.io/bobcat/) See also section ref(IFDNBUF). it() The ti(open) member initializes the buffer. Using hi(setp)tt(streambuf::setp), the begin and end points of the buffer are defined. This is used by the tt(streambuf) base class to initialize hi(pbase)tt(streambuf::pbase), hi(pptr)tt(streambuf::pptr), and hi(epptr)tt(streambuf::epptr): verbinclude(//OPEN examples/fdout.h) it() The member ti(sync) flushes the as yet unflushed content of the buffer to the device. After the flush the buffer is reinitialized using tt(setp). After successfully flushing the buffer tt(sync) returns 0: verbinclude(//SYNC examples/fdout.h) it() The member hi(overflow)tt(streambuf::overflow) is also overridden. Since this member is called from the tt(streambuf) base class when the buffer is full it should first call tt(sync) to flush the buffer to the device. Next it should write the character tt(c) to the (now empty) buffer. The character tt(c) should be written using tt(pptr) and hi(pbump)tt(streambuf::pbump). Entering a character into the buffer should be implemented using available tt(streambuf) member functions, rather than `by hand' as doing so might invalidate tt(streambuf)'s internal bookkeeping. Here is tt(overflow)'s implementation: verbinclude(//OVERFLOW examples/fdout.h) ) The next program uses the tt(OFfdStreambuf) class to copy its standard input to file descriptor ti(STDOUT_FILENO), which is the symbolic name of the file descriptor used for the standard output: verbinclude(-a examples/fdout.cc) c++-annotations-12.5.0/yo/concrete/rules.yo0000644000175000017500000000233314466730207017434 0ustar frankfrank The rules and actions of the grammar are specified as usual. The grammar for our little calculator is given below. There are quite a few rules, but they illustrate various features offered by tt(bisonc++). In particular, note that no action block requires more than a single line of code. This keeps the grammar simple, and therefore enhances its readability and understandability. Even the rule defining the parser's proper termination (the empty line in the tt(line) rule) uses a single member function called tt(done). The implementation of that function is simple, but it is worth while noting that it calls bf(Parser::ACCEPT), showing that bf(ACCEPT) can be called indirectly from a production rule's action block. Here are the grammar's production rules: verbinclude(//RULES bisonc++/parser/grammar) This grammar is used to implement a simple calculator in which integer and real values can be negated, added, and multiplied and in which standard priority rules can be overruled by parentheses. The grammar shows the use of typed nonterminal symbols: tt(doubleExpr) is linked to real (double) values, tt(intExpr) is linked to integer values. Precedence and type association is defined in the parser's definition section. c++-annotations-12.5.0/yo/concrete/lexerspec.yo0000644000175000017500000000324114466730207020273 0ustar frankfrank The i(lexical scanner specification file) is organized comparably to the one used for tt(flex) in bf(C) contexts. However, in bf(C++) contexts, tt(flexc++) creates a class tt(Scanner), rather than just a scanner function. Flexc++'s specification file consists of two sections: itemization( it() The specification file's first section is tt(flexc++)'s emi(symbol area), used to define symbols, like a i(mini scanner), or emi(options). The following options are suggested: itemization( it() ti(%debug): includes em(debugging) hi(flexc++: debugging) code into the code generated by tt(flexc++). Calling the member function hi(setDebug) tt(setDebug(true)) activates this debugging code at run-time. When activated, information about the matching process is written to the standard output stream. The execution of debug code is suppressed after calling the member function tt(setDebug(false)). it() ti(%filenames): defines the base-name of the class header files generated by tt(flexc++). By default the class name (itself using the default tt(Scanner)) is used. ) Here is the specification files' symbol area: verbinclude(//SYMBOLS lexer/scanner/lexer) it() The specification file's second section is a em(rules section) in which the regular expressions and their associated actions are defined. In the example developed here, the lexer should copy information from the standard input stream (tt(std::cin)) to the standard output stream (tt(std::cout)). For this the predefined macro ti(ECHO) can be used. Here are the rules: verbinclude(//RULES lexer/scanner/lexer) ) c++-annotations-12.5.0/yo/concrete/monitorexample.yo0000644000175000017500000000755714466730207021362 0ustar frankfrank Now that tt(run)'s implementation has been covered, we'll concentrate on the various commands users might enter: itemization( it() When the tt(start) command is issued, a new child process is started. A new element is added to tt(d_child) by the member tt(createNewChild). Next, the tt(Child) object should start its activities, but the tt(Monitor) object can not wait for the child process to complete its activities, as there is no well-defined endpoint in the near future, and the user probably wants to be able to enter more commands. Therefore, the tt(Child) process must run as a emi(daemon). So the forked process terminates immediately, but its own child process continues to run (in the background). Consequently, tt(createNewChild) calls the child's tt(fork) member. Although it is the child's tt(fork) function that is called, it is still the monitor program wherein that tt(fork) function is called. So, the em(monitor) program is duplicated by tt(fork). Execution then continues: itemization( it() At the tt(Child)'s tt(parentProcess) in its parent process; it() At the tt(Child)'s tt(childProcess) in its child process ) As the tt(Child)'s tt(parentProcess) is an empty function, returning immediately, the tt(Child)'s parent process effectively continues immediately below tt(createNewChild)'s tt(cp->fork()) statement. As the child process never returns (see section ref(CHILD)), the code below tt(cp->fork()) is never executed by the tt(Child)'s child process. This is exactly as it should be. In the parent process, tt(createNewChild)'s remaining code simply adds the file descriptor that's available for reading information from the child to the set of input file descriptors monitored by tt(d_select), and uses tt(d_child) to establish the association between that file descriptor and the tt(Child) object's address: verbinclude(//CHILD examples/monitor/createnewchild.cc) it() Direct communication with the child is required for the tt(stop ) and tt( text) commands. The former command terminates child process tt(), by calling tt(stopChild). This function locates the child process having the order number using an anonymous object of the class tt(Find), nested inside tt(Monitor). The class tt(Find) simply compares the provided tt(nr) with the children's order number returned by their tt(nr) members: verbinclude(//FINDIMP examples/monitor/monitor.h) If the child process having order number tt(nr) was found, its file descriptor is removed from tt(d_selector)'s set of input file descriptors. Then the child process itself is terminated by the static member tt(killChild). The member tt(killChild) is declared as a em(static) member function, as it is used as function argument of the tt(for_each) generic algorithm by tt(exiting) (see below). Here is tt(killChild)'s implementation: verbinclude(//KILL examples/monitor/monitor.cc) Having terminated the specified child process, the corresponding tt(Child) object is destroyed and its pointer is removed from tt(d_child): verbinclude(//STOP examples/monitor/stopchild.cc) it() The command tt( text) sends tt(text) to child process tt(nr) using the member function tt(sendChild). This function also uses a tt(Find) object to locate the child-process having order number tt(nr), and simply inserts the text into the writing end of a pipe connected to that child process: verbinclude(//SEND examples/monitor/sendchild.cc) it() When users enter tt(exit) or tt(quit) the member tt(exiting) is called. It terminates all child processes using the ti(for_each) generic algorithm (see section ref(FOREACH)) to visit all elements of tt(d_child). Then the program itself ends: verbinclude(//EXIT examples/monitor/monitor.cc) ) The program's tt(main) function is simple and needs no further comment: verbinclude(//MAIN examples/monitor/main.cc) c++-annotations-12.5.0/yo/concrete/scanmain.yo0000644000175000017500000000140414466730207020071 0ustar frankfrank The program using our tt(Scanner) is very simple. It expects a filename indicating where to start the scanning process. The program first checks the number of arguments. If at least one argument was given, then that argument is passed to tt(Scanner)'s constructor, together with a second argument tt("-"), indicating that the output should go to the standard output stream. If the program receives more than one argument debug output, extensively documenting the lexical scanner's actions, is written to the standard output stream as well. Next the tt(Scanner)'s tt(lex) member is called. If anything fails, a tt(std::exception) is thrown, which is caught by tt(main)'s try-block's catch clause. Here is the program's source: verbinclude(-a lexer/lexer.cc) c++-annotations-12.5.0/yo/concrete/unrestricted/0000755000175000017500000000000014624637124020443 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/unrestricted/input0000644000175000017500000000002514466730207021522 0ustar frankfrankabc(def); xyz = 5; c++-annotations-12.5.0/yo/concrete/unrestricted/semantic/0000755000175000017500000000000014624637124022246 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/unrestricted/semantic/semantic2.cc0000664000175000017500000000042014624637131024436 0ustar frankfrank#include "semantic.ih" Semantic::Semantic(Semantic const &other) : d_int(other.d_int) // blunt copy of d_int { if (d_int.first == IDENTIFIER) // if a string: copy it new (&d_str.second) string{ other.d_str.second }; } c++-annotations-12.5.0/yo/concrete/unrestricted/semantic/semantic1.cc0000664000175000017500000000041514624637131024441 0ustar frankfrank#include "semantic.ih" Semantic::Semantic(Type type, char const *txt) { d_int.first = static_cast(type); if (type == IDENTIFIER) new (&d_str.second) string{ txt }; else { istringstream in(txt); in >> d_int.second; } } c++-annotations-12.5.0/yo/concrete/unrestricted/semantic/semantic.ih0000664000175000017500000000012314624637127024374 0ustar frankfrank#include "semantic.h" #include #include using namespace std; c++-annotations-12.5.0/yo/concrete/unrestricted/semantic/semantic.h0000664000175000017500000000122214624637127024224 0ustar frankfrank#ifndef INCLUDED_SEMANTIC_ #define INCLUDED_SEMANTIC_ #include #include union Semantic { friend std::ostream &operator<<(std::ostream &out, Semantic const &obj); std::pair d_int; std::pair d_str; public: enum Type { INT, IDENTIFIER }; Semantic(); Semantic(Type type, char const *txt); Semantic(Semantic const &other); // 2 ~Semantic(); Semantic &operator=(Semantic const &rhs); void swap(Semantic &other); }; inline Semantic::Semantic() : d_int {INT, 0} {} #endif c++-annotations-12.5.0/yo/concrete/unrestricted/semantic/operatorinsert.cc0000664000175000017500000000035214624637131025635 0ustar frankfrank#include "semantic.ih" std::ostream &operator<<(std::ostream &out, Semantic const &obj) { if (obj.d_int.first == Semantic::IDENTIFIER) out << obj.d_str.second; else out << obj.d_int.second; return out; } c++-annotations-12.5.0/yo/concrete/unrestricted/semantic/destructor.cc0000664000175000017500000000023414624637131024752 0ustar frankfrank#include "semantic.ih" Semantic::~Semantic() { if (d_int.first == IDENTIFIER) d_str.second.~string(); // destroy the string's memory } c++-annotations-12.5.0/yo/concrete/unrestricted/semantic/operatorassign.cc0000664000175000017500000000020714624637131025614 0ustar frankfrank#include "semantic.ih" Semantic &Semantic::operator=(Semantic const &rhs) { Semantic tmp(rhs); swap(tmp); return *this; } c++-annotations-12.5.0/yo/concrete/unrestricted/semantic/swap.cc0000664000175000017500000000043714624637131023533 0ustar frankfrank#include "semantic.ih" void Semantic::swap(Semantic &other) { char buffer[sizeof(Semantic)]; memcpy(buffer, this, sizeof(Semantic)); memcpy(reinterpret_cast(this), &other, sizeof(Semantic)); memcpy(reinterpret_cast(&other), buffer, sizeof(Semantic)); } c++-annotations-12.5.0/yo/concrete/unrestricted/parser/0000755000175000017500000000000014624637123021736 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/unrestricted/parser/parser.h0000664000175000017500000000202014624637127023403 0ustar frankfrank#ifndef Parser_h_included #define Parser_h_included // $insert baseclass #include "parserbase.h" // $insert scanner.h #include "../scanner/scanner.h" #undef Parser class Parser: public ParserBase { // $insert scannerobject Scanner d_scanner; public: Parser(); int parse(); private: void error(char const *msg); // called on (syntax) errors int lex(); // returns the next token from the // lexical scanner. void print(); // use, e.g., d_token, d_loc // support functions for parse(): void executeAction(int ruleNr); void errorRecovery(); int lookup(bool recovery); void nextToken(); }; inline void Parser::error(char const *msg) { std::cerr << msg << '\n'; } // $insert lex inline int Parser::lex() { return d_scanner.yylex(); } inline void Parser::print() // use d_token, d_loc {} inline Parser::Parser() : d_scanner(&d_val__) {} #endif c++-annotations-12.5.0/yo/concrete/unrestricted/parser/parser.ih0000664000175000017500000000017314624637127023563 0ustar frankfrank // Include this file in the sources of the class Parser. // $insert class.h #include "parser.h" using namespace std; c++-annotations-12.5.0/yo/concrete/unrestricted/parser/grammar0000644000175000017500000000063714466730207023316 0ustar frankfrank%class-name Parser %filenames parser %parsefun-source parse.cc %scanner ../scanner/scanner.h // %debug %baseclass-preinclude preinclude.h %stype Semantic %token INT IDENTIFIER %% rules: rules rule | rule ; rule: IDENTIFIER '(' IDENTIFIER ')' ';' { cout << $1 << " " << $3 << '\n'; } | IDENTIFIER '=' INT ';' { cout << $1 << " " << $3 << '\n'; } ; c++-annotations-12.5.0/yo/concrete/unrestricted/parser/preinclude.h0000664000175000017500000000015114624637127024244 0ustar frankfrank#ifndef INCLUDED_PREINCLUDE_H_ #define INCLUDED_PREINCLUDE_H_ #include "../semantic/semantic.h" #endif c++-annotations-12.5.0/yo/concrete/unrestricted/scanner/0000755000175000017500000000000014624637123022073 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/unrestricted/scanner/scanner.ih0000664000175000017500000000175614624637127024065 0ustar frankfrank/* Declare here what's only used in the Scanner class and let Scanner's sources include "scanner.ih" */ #include "scanner.h" //#include // #include // #include // #include /* In the current Debian distribution of flex, YY_CURRENT_BUFFER and YY_START are not available to members of the flex-generated class (See `Values Available To The User' in the flex info-file). Use the following macros to make these values available. (Note that the need for these defines may be superfluous in the near future): */ // uncomment if you want to use YY_CURRENT_BUFFER in the scanner's members: /* #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) */ // uncomment if you want to use YY_START in the scanner's members: // #define YY_START (((yy_start) - 1) / 2) // end of scanner.ih c++-annotations-12.5.0/yo/concrete/unrestricted/scanner/scanner.h0000664000175000017500000000066514624637127023712 0ustar frankfrank#ifndef SCANNER_H_ #define SCANNER_H_ #include "../semantic/semantic.h" #if ! defined(SKIP_FLEXLEXER_) && ! defined(SYSINC_FLEXLEXER_H_) #include #define SYSINC_FLEXLEXER_H_ #endif class Scanner: public yyFlexLexer { Semantic *d_semval; // received fm the parser public: Scanner(Semantic *semval); int yylex(); }; inline Scanner::Scanner(Semantic *semval) : d_semval(semval) {} #endif c++-annotations-12.5.0/yo/concrete/unrestricted/scanner/lexer0000644000175000017500000000121314466730207023133 0ustar frankfrank%{ #define SKIP_FLEXLEXER_ #include "scanner.ih" #include "../parser/preinclude.h" #include "../parser/parserbase.h" %} %option yyclass="Scanner" outfile="yylex.cc" %option c++ 8bit warn noyywrap yylineno %option debug %% [ \t]+ // skip white space \n // same [0-9]+ { *d_semval = Semantic(Semantic::INT, yytext); return Parser::INT; } [a-zA-Z_][a-zA-Z0-9_]* { *d_semval = Semantic(Semantic::IDENTIFIER, yytext); return Parser::IDENTIFIER; } . return yytext[0]; %% c++-annotations-12.5.0/yo/concrete/unrestricted/icmconf0000644000175000017500000000675014466730207022014 0ustar frankfrank // Inspect the following #defines. Change them to taste. If you don't // need a particular option, change its value into an empty string // should commands be echoed (ON) or not (OFF) ? #define USE_ECHO ON // The final program and source containing main(): // =============================================== // define the name of the program to create: #define BINARY "../../poly" // define the name of the source containing main(): #define MAIN "main.cc" // #defines used for compilation and linking: // ========================================== // define the compiler to use: #define COMPILER "g++" // define the compiler options to use: #define COMPILER_OPTIONS "-g --std=c++0x -Wall -O2" // define the pattern to locate sources in a directory: #define SOURCES "*.cc" // define the options used for linking: #define LINKER_OPTIONS "-s" // define any additional libraries BINARY may need: #define ADD_LIBRARIES "bobcat" // define any additional paths (other than the standard paths) the // additional libraries are located in: #define ADD_LIBRARY_PATHS "" // #defines used for the final product: // ==================================== #define BIN_INSTALL "/usr/local/bin" // Some advanced #defines, used to create parsers and lexical scanners // =================================================================== // Lexical Scanner section // ======================= // Should a lexical scanner be constructed? If so, define the subdirectory // containing the scanner's specification file. #define SCANNER_DIR "scanner" // What is the program generating the lexical scanner? #define SCANGEN "flex" // Flags to provide SCANGEN with: #define SCANFLAGS "-I" // Name of the lexical scanner specification file #define SCANSPEC "lexer" // Name of the file generated by the lexical scanner #define SCANOUT "yylex.cc" // Parser section // ============== // Should a parser be constructed? If so, define the subdirectory // containing the parser's specification file #define PARSER_DIR "parser" // If a parser must be constructed, should the script (provided in the // skeleton file parser/gramspec/grambuild) `parser/gramspec/grambuild' // **NOT** be called? If it must NOT be called, comment out the following // #define directive: // #define GRAMBUILD // What it the program generating a parser? #define PARSGEN "bisonc++" // What it the grammar specificication file? #define PARSSPEC "grammar" // Flags to provide PARSGEN with: #define PARSFLAGS "-V -l" // Name of the file generated by the parser generator containing the // parser function #define PARSOUT "parse.cc" // Additional defines, which should normally not be modified // ========================================================= // Directory below this directory to contain temporary results #define TMP_DIR "tmp" // Local program library to use (change to an empty string if you want to // use the object modules themselves, rather than a library) #define LIBRARY "modules" // The extension of object modules: #define OBJ_EXT ".o" // below #define DEFCOM "program" or "library" may be added by icmstart #define DEFCOM "program" c++-annotations-12.5.0/yo/concrete/unrestricted/main.cc0000664000175000017500000000020114624637131021667 0ustar frankfrank#include "main.ih" int main(int argc, char **argv) { Parser parser; parser.setDebug(argc == 1); parser.parse(); } c++-annotations-12.5.0/yo/concrete/unrestricted/main.ih0000664000175000017500000000016314624637127021716 0ustar frankfrank#include #include #include #include "parser/preinclude.h" #include "parser/parser.h" c++-annotations-12.5.0/yo/concrete/unrestricted/CLASSES0000644000175000017500000000001114466730207021453 0ustar frankfranksemantic c++-annotations-12.5.0/yo/concrete/command.yo0000644000175000017500000000131114466730207017713 0ustar frankfrank The tt(class Command) defines the interface to be used for scanning commands from the standard input. Its constructor expects an array of strings, which are the commands to be recognized, as well as the number of commands. The command tt(\d) represents a digit, tt(*) represents any text until end of line. Blanks may appear before or after the commands. The class does nothing fancy: if anything more complex is required, a formal emi(grammar) should be specified (see section(BISONFLEX)). Its member tt(int next(std::string &text)) returns the number of the interpreted command, with tt(text) containing the actual text that was received. Here is the class interface: verbinclude(-a examples/command.h) c++-annotations-12.5.0/yo/concrete/fistream.yo0000644000175000017500000000775414466730207020130 0ustar frankfrankUsually when extracting information from tt(istream) objects oprshift(), the standard extraction operator is perfectly suited for the task as in most cases the extracted fields are white-space (or otherwise clearly) separated from each other. But this does not hold true in all situations. For example, when a web-form is posted to some processing script or program, the receiving program may receive the form field's values as em(url-encoded) characters: letters and digits are sent unaltered, blanks are sent as tt(+) characters, and all other characters start with tt(%) followed by the character's i(ascii-value) represented by its two digit hexadecimal value. When decoding url-encoded information, simple hexadecimal extraction won't work, as that extracts as many hexadecimal characters as available, instead of just two. Since the letters tt(a-f`) and tt(0-9) are legal hexadecimal characters, a text like tt(My name is `Ed'), url-encoded as verb( My+name+is+%60Ed%27) results in the extraction of the hexadecimal values tt(60ed) and tt(27), instead of tt(60) and tt(27). The name tt(Ed) disappears from view, which is clearly not what we want. In this case, having seen the tt(%), we could extract 2 characters, put them in an ti(istringstream) object, and extract the hexadecimal value from the tt(istringstream) object. A bit cumbersome, but doable. Other approaches are possible as well. The class ti(Fistream) for em(fixed-sized field istream) defines an tt(istream) class supporting both fixed-sized field extractions and blank-delimited extractions (as well as unformatted tt(read) calls). The class may be initialized as a emi(wrapper) around an existing tt(istream), or it can be initialized using the name of an existing file. The class is derived from tt(istream), allowing all extractions and operations supported by tt(istream)s in general. tt(Fistream) defines the following data members: itemization( itt(d_filebuf): a filebuffer used when tt(Fistream) reads its information from a named (existing) file. Since the filebuffer is only needed in that case, and since it must be allocated dynamically, it is defined as a tt(unique_ptr) object. itt(d_streambuf): a pointer to tt(Fistream)'s tt(streambuf). It points to tt(d_filebuf) when tt(Fistream) opens a file by name. When an existing tt(istream) is used to construct an tt(Fistream), it points to the existing tt(istream)'s tt(streambuf). itt(d_iss): an tt(istringstream) object used for the fixed field extractions. itt(d_width): a tt(size_t) indicating the width of the field to extract. If 0 no fixed field extractions is used, but information is extracted from the tt(istream) base class object using standard extractions. ) Here is the initial section of tt(Fistream)'s class interface: verbinclude(//INITIAL examples/fistream/fistream.h) As stated, tt(Fistream) objects can be constructed from either a filename or an existing tt(istream) object. The class interface therefore declares two constructors: verbinclude(//CONS examples/fistream/fistream.h) When an tt(Fistream) object is constructed using an existing tt(istream) object, the tt(Fistream)'s tt(istream) part simply uses the tt(stream)'s tt(streambuf) object: verbinclude(//CONS1 examples/fistream/fistream.cc) When an tt(fstream) object is constructed using a filename, the tt(istream) base initializer is given a new tt(filebuf) object to be used as its tt(streambuf). Since the class's data members are not initialized before the class's base class has been constructed, tt(d_filebuf) can only be initialized thereafter. By then, the tt(filebuf) is only available as tt(rdbuf), returning a tt(streambuf). However, as it is actually a tt(filebuf), a tt(static_cast) is used to cast the tt(streambuf) pointer returned by tt(rdbuf) to tt(a filebuf *), so tt(d_filebuf) can be initialized: verbinclude(//CONS2 examples/fistream/fistream.cc) c++-annotations-12.5.0/yo/concrete/addtypes.yo0000644000175000017500000000070614466730207020121 0ustar frankfrankThese are the steps to take when another semantic data type must be added to an existing set: itemization( it() Add a tag name representing the new semantic value type to the tt(enum class Tag) (section ref(TAG)); it() Add a specialization to the tt(TagTrait) trait class (section ref(TAGTRAIT)) defining the added semantic value's data type, and whether or not the data on the parser's semantic stack should be considered (im)mutable. ) c++-annotations-12.5.0/yo/concrete/proxy.yo0000644000175000017500000001300714466730207017463 0ustar frankfrankA problem with ti(operator[]) is that it can't distinguish between its hi(lvalue: distinguish from rvalue)hi(rvalue: distinguish from lvalue) use as an em(lvalue) and as an em(rvalue). It is a familiar misconception to think that verb( Type const &operator[](size_t index) const) is used as em(rvalue) (as the object isn't modified), and that verb( Type &operator[](size_t index)) is used as em(lvalue) (as the returned value can be modified). The compiler, however, distinguishes between the two operators only by the tt(const)-status of the object for which tt(operator[]) is called. With tt(const) objects the former operator is called, with non-tt(const) objects the latter is always used. It is always used, irrespective of it being used as lvalue or rvalue. Being able to distinguish between lvalues and rvalues can be very useful. Consider the situation where a class supporting tt(operator[]) stores data of a type that is very hard to copy. With data like that reference counting (e.g., using tt(shared_ptr)s) is probably used to prevent needless copying. As long as tt(operator[]) is used as rvalue there's no need to copy the data, but the information em(must) be copied if it is used as lvalue. The emi(Proxy Design Pattern) (cf. hi(Gamma, E.)em(Gamma et al.) (1995)) can be used to distinguish between lvalues and rvalues. With the Proxy Design Pattern an object of another class (the Proxy class) is used to act as a em(stand in) for the `real thing'. The proxy class offers functionality that cannot be offered by the data themselves, like distinguishing between its use as lvalue or rvalue. A proxy class can be used in many situations where access to the real data cannot or should not be directly provided. In this regard em(iterator) types are examples of proxy classes as they create a layer between the real data and the software using the data. Proxy classes could also dereference pointers in a class storing its data by pointers. In this section we concentrate on the distinction between using tt(operator[]) as lvalue and rvalue. Let's assume we have a class tt(Lines) storing lines from a file. Its constructor expects the name of a stream from which the lines are read and it offers a non-const tt(operator[]) that can be used as lvalue or rvalue (the tt(const) version of tt(operator[]) is omitted as it causes no confusion because it is always used as rvalue): verbinclude(//LINES examples/lines0.h) To distinguish between lvalues and rvalues we must find distinguishing characteristics of lvalues and rvalues that we can exploit. Such distinguishing characteristics are tt(operator=) (which is always used as lvalue) and the conversion operator (which is always used as rvalue). Rather than having tt(operator[]) return a tt(string &) we can let it return a tt(Proxy) object that is able to distinguish between its use as lvalue and rvalue. The class tt(Proxy) thus needs tt(operator=(string const &other)) (acting as lvalue) and tt(operator std::string const &() const) (acting as rvalue). Do we need more operators? The tt(std::string) class also offers tt(operator+=), so we should probably implement that operator as well. Plain characters can also be assigned to tt(string) objects (even using their numeric values). As tt(string) objects cannot be em(constructed) from plain characters em(promotion) cannot be used with tt(operator=(string const &other)) if the right-hand side argument is a character. Implementing tt(operator=(char value)) could therefore also be considered. These additional operators are left out of the current implementation but `real life' proxy classes should consider implementing these additional operators as well. Another subtlety is hi(Proxy: stream insertion and extraction) that tt(Proxy)'s tt(operator std::string const &() const) is not used when using tt(ostream)'s insertion operator or tt(istream)'s extraction operator as these operators are implemented as templates not recognizing our tt(Proxy) class type. So when stream insertion and extraction is required (it probably is) then tt(Proxy) must be given its own overloaded insertion and extraction operator. Here is an implementation of the overloaded insertion operator inserting the object for which tt(Proxy) is a stand-in: verbinclude(//INSERT examples/lines.h) There's no need for any code (except tt(Lines)) to create or copy tt(Proxy) objects. tt(Proxy)'s constructor should therefore be made private, and tt(Proxy) can declare tt(Lines) to be its friend. In fact, tt(Proxy) is intimately related to tt(Lines) and can be defined as a nested class. In the revised tt(Lines) class tt(operator[]) no longer returns a tt(string) but instead a tt(Proxy) is returned. Here is the revised tt(Lines) class, including its nested tt(Proxy) class: verbinclude(//LINES examples/lines.h) tt(Proxy)'s members are very lightweight and can usually be implemented inline: verbinclude(//MEMBERS examples/lines.h) The member tt(Lines::operator[]) can also be implemented inline: it merely returns a tt(Proxy) object initialized with the tt(string) associated with index tt(idx). Now that the class tt(Proxy) has been developed it can be used in a program. Here is an example using the tt(Proxy) object as lvalue or rvalue. On the surface tt(Lines) objects won't behave differently from tt(Lines) objects using the original implementation, but by adding an identifying tt(cout) statement to tt(Proxy)'s members it can be shown that tt(operator[]) behaves differently when used as lvalue or as rvalue: verbinclude(//MAIN examples/lines.cc) c++-annotations-12.5.0/yo/concrete/access.yo0000644000175000017500000000356314466730207017551 0ustar frankfrankHow to access the data that are actually stored inside a semantic value class that is derived from the semantic values polymorphic base class? Depending on the status (mutable or immutable) and type (basic or class type) of the actual semantic data we recognize three situations: itemization( it() If the data within the semantic value class are mutable, then an accessor should return a reference to the data stored within the semantic value class; it() Immutable non-class type values should be made available by value; it() Immutable class type values should be made available as const references. ) Next, a trait class template tt(Trait) is defined, requiring a tt(Tag) template non-type parameter. This trait class uses the tt(Tag) to determine the data type that is associated with the tt(Tag), making its local type tt(DataType) as synonym of that data type. Next, to determine whether an actual data type is a class type or a basic type template meta programming, as outlined in section ref(CLASSORNOT), is used. Using template meta programming a value tt(isBasicType) of an tt(enum: bool) anonymous enum is set to true if tt(DataType) represents a basic data type. This enum also defines a value tt(isMutable) indicating whether or not the actual data stored in a semantic value class is mutable or not. Next, conditional to the combinations of tt(isMutable) and tt(isBasicType) the tt(Trait) trait class defines the type tt(ReturnType). For this the available tt(std::conditional) trait class is used (cf. section ref(TYPETRAITS)). Now we're able, e.g., to state tt(Trait::DataType) to obtain the tt(int) data type, or to state tt(Trait::ReturnType) to obtain the `tt(std::vector> &)' return type. Here is the implementation of the trait class template tt(Trait): verbinclude(//CLASSTRAIT poly2/sembase/sembase.h) c++-annotations-12.5.0/yo/concrete/namespace.yo0000644000175000017500000000147114466730207020240 0ustar frankfrankWhen using the function template tt(Binary operator+(Binary const &lhs, Binary const &rhs)), however, we may encounter a subtle and unexpected complication. Consider the following program. When run, it displays the value 12, rather than 1: verb( enum Values { ZERO, ONE }; template Tp operator+(Tp const &lhs, Tp const &rhs) { return static_cast(12); }; int main() { cout << (ZERO + ONE); // shows 12 }) This complication can be avoided by defining the operators in their own namespace, but then all classes using the binary operator also have to be defined in that namespace, which is not a very attractive restriction. Fortunately, there is a better alternative: using the CRTP (cf. section ref(STATICPOLY)). c++-annotations-12.5.0/yo/concrete/spsembase.yo0000644000175000017500000000051714466730207020266 0ustar frankfrankThe parser uses tt(spSemBase) as its semantic value. The class tt(spSemBase) is a wrapper around tt(std::shared_ptr), offering a constructor member template which must be given a pointer to a dynamically allocated tt(Semantic) object. Its interface is all that is required: verbinclude(-a poly2/spsembase/spsembase.h) c++-annotations-12.5.0/yo/concrete/tag.yo0000644000175000017500000000037214466730207017056 0ustar frankfrankOur program handles three types of semantic values: numbers, text, and vectors of semantic values, which are either numbers or text. These distinct types are indicated by em(tag) enumeration values: verbinclude(//TAG poly2/sembase/sembase.h) c++-annotations-12.5.0/yo/concrete/scanner.yo0000644000175000017500000000424014466730207017732 0ustar frankfrank The tt(class Scanner) is generated once by bi(flexc++). This class has access to several members defined by its base class tt(ScannerBase). Some of these members have public access rights and can be used by code external to the class tt(Scanner). These members are extensively documented in the bf(flexc++)(1) man-page, and the reader is referred to this man-page for further information. Our scanner performs the following tasks: itemization( it() it matches regular expressions, ignoring comment, and writing the matched text to the standard output stream; it() it switches to other files, and returns to the previous file once a file has completely been processed, ending the lexical scan once the end of the first input file has been reached. ) The tt(#include) statements in the input allow the scanner to distill the name of the file where the scanning process must continue. This file name is stored in a local variable tt(d_nextSource) and a member tt(stackSource) handles the switch to the next source. Nothing else is required. Pushing and popping input files is handled by the scanner's members tt(pushStream) and tt(popStream), provided by tt(flexc++). tt(Scanner)'s interface, therefore, only needs one additional function declaration: tt(switchSource). Switching streams is handled as follows: once the scanner has extracted a filename from an tt(#include) directive, a switch to another file is realized by tt(switchSource). This member calls tt(pushStream), defined by tt(flexc++), to stack the current input stream and to switch to the stream whose name is stored in tt(d_nextSource). This also ends the tt(include) mini-scanner, so to return the scanner to its default scanning mode tt(begin(StartCondition__::INITIAL)) is called. Here is its source: verbinclude(-a lexer/scanner/switchsource.cc) The member tt(pushStream), defined by tt(flexc++), handles all necessary checks, throwing an exception if the file could not be opened or if too many files are stacked. The member performing the lexical scan is defined by tt(flexc++) in tt(Scanner::lex), and this member can be called by code to process the tokens returned by the scanner. c++-annotations-12.5.0/yo/concrete/polymorphic.yo0000644000175000017500000000755314466730207020660 0ustar frankfrankInstead of using unions to store various semantic values tt(bisonc++) could also use a polymorphic base class to handle semantic values of various types. Using a polymorphic base class is covered in this section. The described method is a direct result of a suggestion initially brought forward by Dallas A. Clement in September 2007. One may wonder why tt(union)s are still used by Bisonc++, as bf(C++) offers inherently superior ways to handle multiple semantic types: a poymorphic base class and a series of derived classes implementing the alternative data types. On the other hand, a polymorphic base class also seems to imply a lot of additional work: classes must be derived from a base class, virtual members must be declared and overridden in derived classes, and the base class must be aware of the relevant interfaces of all derived classes. All this does more to hinder than to promote the construction of reusable software. So, how to proceed? It turns out that the required effort to implement and use polymorphic semantic values is fairly small. In fact, only a very basic polymorphic semantic base class needs to be implemented. Having defined the polymorphic base class template meta programming techniques can be used to let the compiler create all derived classes we might need. The amount of works turns out to be astonishingly small. What about the `free lunch'? Well, the approach works fine in situations where we either can deduce the actual semantic value from the grammar (i.e., the syntax) itself, or where we occasionally are willing to use a switch to select the actual semantic value. This rather weak assumption holds true for the grammar used by the program developed in this section, so let's get on with it! The program developed in this section recognizes input consisting of lines suggesting assignment statements or function calls: verb( value: int | ident ; arglist: arglist ',' value | value ; rule: ident '(' arglist ')' ';' | ident '=' int ';' ;) An essential characteristic of these simple rules is that three different semantic value types are used: int-values, names, and vectors of arguments. Other types could easily be used as well: doubles, complex numbers, sets; you name it. Our semantic value must accommodate all of these different types, and must also allow us to determine the actual type that's stored in a semantic value in cases where we cannot deduce the actual type merely from the syntax (which happens, e.g., for the various semantic value types that may be contained in an tt(arglist)). In the following sections we'll develop the parser using a polymorphic base class to handle its semantic values. To prevent excessive copying of semantic values the parser's actual semantic value is not the semantic value itself but a tt(spSemBase), which is a wrapper around a tt(std::shared_ptr), where tt(SemBase) is our polymorphic base class (cf. section ref(SPSEMBASE)). We'll develop the generic tt(Semantic) class template in steps: itemization( it() In the next section we'll start by defining em(tags) for the various semantic data types; it() Next, support structs are developed allowing us to indicate whether semantic data can be modified by the parser or not; it() Following this, a trait class is developed allowing us to obtain data types from tags; it() Another trait class is needed to determine the data type that is returned by the conversion operators of the different semantic data types; it() Hereafter the polymorphic base class tt(SemBase) is developed; it() Finally, de class template tt(Semantic) is defined, allowing us to define various semantic value classes, all derived from tt(SemBase) ) The complete demo program is available in the annotations()'s source archive under the directory tt(yo/concrete/poly2). c++-annotations-12.5.0/yo/concrete/unrestricted.yo0000644000175000017500000000704714466730207021024 0ustar frankfrankUnions revived in bf(C++) with the advent of unrestricted unions. In this section we'll have a look at how to used them as semantic values in a Bisonc++ generated parser. The just developed polymorphic semantic value had to support itemization( itt(int) values; itt(textual) values of type tt(string); ) When unrestricted unions are used, the union must be able to support tt(int) and tt(string) values. Using the tt(pair) to allow the union to do `introspection' (cf. section ref(UNIONS)), we now define a em(union) tt(Semantic) having the following data members: verb( std::pair d_int; std::pair d_str;) Since an unrestricted union by default deletes all its standard constructors and operators (it must do so, as it cannot tell which data variant is currently active) they must all be implemented explicitly by the tt(Semantic) union. To aid the introspection a type is defined, indicating whether the variant is an tt(int) or a tt(string), and the default constructor simply defines an tt(INT) value 0. Here is tt(Semantic)'s interface: verbinclude(-a unrestricted/semantic/semantic.h) tt(Semantic) objects are as big as required to accommodate all its variants. However, as tt(Semantic) is a union, its constructors and destructor cannot predefine or destroy all of its variants. Rather, it must pick the appropriate field based on the tt(pair)'s tt(first) field. For tt(int) values a simple assignment is OK, but for tt(string) values a constructor and destructor must be used. For this, placement new and an explicit destructor call is required. Here are tt(Semantic)'s tt(Semantic(Type, char const *)), its copy constructor and its destructor: verbinclude(-a unrestricted/semantic/semantic1.cc) verbinclude(-a unrestricted/semantic/semantic2.cc) verbinclude(-a unrestricted/semantic/destructor.cc) Our little parser only needs to be able to insert semantic values. For this an overloaded insertion operator can be used: verbinclude(-a unrestricted/semantic/operatorinsert.cc) The remaining members (tt(operator=, swap)) are standard, and need no further explanation. As tt(Semantic) objects know what type of value they represent, the parser's grammar specification needs no modification. Minor modifications for the scanner's specification, tt(lexer), however are required. Since tt(Semantic) is no longer a wrapper class for a polymorphic base class, using a shared pointer, the previously used tt(shared_ptr)'s tt(reset) calls need to be replaced by direct assignments of tt(Semantic) values to the tt(*d_semval) semantic value. The relevant section of the scanner's specification file tt(lexer) now becomes: verb( [0-9]+ { *d_semval = Semantic(Semantic::INT, yytext); return Parser::INT; } [a-zA-Z_][a-zA-Z0-9_]* { *d_semval = Semantic(Semantic::IDENTIFIER, yytext); return Parser::IDENTIFIER; }) This is all that is required to change a parser using a polymorphic base class to a parser using an unrestricted union. As memory allocation using placement new is fast, an unrestricted union is an efficient way to store multiple data types. Moreover, the semantic value classes implementing the polymorphic semantic value behavior, tt(Base, Int), and tt(Text) are no longer required, nor is the use of the tt(shared_ptr) in a wrapper class (the previously used tt(Semantic) value) required anymore. All in, using an unrestricted union for the parser's semantic values seems like a good deal. c++-annotations-12.5.0/yo/concrete/mutable.yo0000644000175000017500000000115614466730207017735 0ustar frankfrankIn cases where the data stored in the classes derived from the polymorphic base class may either or not be mutable by the parser, there must be a way to indicate so when the derived class is created. Two small support structs define tt(isMutable) enum values indicating whether the data should be considered mutable or not. To make matters concrete, let's assume that we'll need tt(INT) and tt(TEXT) semantic values to be immutable, while tt(VECTOR) semantic values need to be mutable. Here are these structs, defined in the anonymous namespace within tt(sembase.h): verbinclude(//MUTABLE poly2/sembase/sembase.h) c++-annotations-12.5.0/yo/concrete/fork2/0000755000175000017500000000000014466730207016753 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fork2/parentprocess/0000755000175000017500000000000014624637123021642 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fork2/parentprocess/parentprocess.h0000664000175000017500000000111114624637127024703 0ustar frankfrank#ifndef INCLUDED_PARENTPROCESS_H_ #define INCLUDED_PARENTPROCESS_H_ #ifndef INCLUDED_IOSFWD_ #include #define INCLUDED_IOSFWD_ #endif namespace FBB { class ParentProcess { public: virtual ~ParentProcess() {} virtual void run // pure virtual function: implement in ( // derived classes int pid, std::istream &readChildCout, std::istream &readChildCerr, std::ostream &writeChildCin ) = 0; }; } #endif c++-annotations-12.5.0/yo/concrete/fork2/build0000755000175000017500000003031214466730207017777 0ustar frankfrank#!/usr/bin/icmake -t. // script generated by the C++ icmake script version 1.62 /* Configurable defines for the build script: CLASSES: string of directory-names under which sources of classes are found. E.g., CLASSES = "class1 class2" All class-names must be stored in one string. If classes are removed from the CLASSES definition or if the names in the CLASSES definition are reordered, the compilation should start again from scratch. */ string CLASSES; void setClasses() { // ADD ADDITIONAL DIRECTORIES CONTAINING SOURCES OF CLASSES HERE // Use the construction `CLASSES += "classname1 classname2";' etc. CLASSES += "pipe ofdnstreambuf ifdnstreambuf opipe cinredirector " "childprocess fork"; } /* COMPILER: "g++" for C++ sources. Do not change this, unless you're sure you want something else. COPT: C-options used by COMPILER ECHO_REQUEST: ON (default) if command echoing is wanted, otherwise: set to OFF GDB: define if gdb-symbolic debug information is wanted (not defined by default) LIBS: Extra libraries used for linking LIBPATH: Extra library-searchpaths used for linking USE_LIBRARY: define this if you want a library for the object modules. Undefined by default: so NO LIBRARY IS USED. PROGRAM: define if a program is to be built. If not defined, library maintenance is assumed. (default: defined) RELINK: Defined by default, causing a program to be relinked every time the script is called. Do not define it if relinking should only occur if a source is compiled. No effect for library maintenance. Current values: */ #define COMPILER "g++" // COPT: the set of C-options #define COPT "--std=c++11 -Wall" #define ECHO_REQUEST ON // #define GDB // Extra libraries required. Remove lib and .a from the library names. // E.g., #define LIBS "m Xt" to link libm.a and libXt.a explicitly // Specify libs from the most specific to the most general one. #define LIBS "" // Extra library-paths required. // E.g., #define LIBPATH "/some/path /some/other/path" to search these paths // apart from the default paths #define LIBPATH "" // uncomment if you WANT to use a library #define USE_LIBRARY // #define PROGRAM #define RELINK // DO NOT ALTER THINGS BELOW THIS LINE string // contain options for libs, // extra libs, e.g., "-lrss -licce" libpath, // extra lib-paths, eg, "-L../rss" copt, lopt, libxxxa; // expanded lib-name int relink; // internally used: != 0 to relink string ofiles, // wildcards for o-files sources, // sources to be used wild, // wildcard of extension current; // contains name of current dir. /* O B J F I L E S . I M */ list objfiles(list files) { string file, objfile; int i; for (i = 0; i < sizeof(files); i++) { file = element(i, files); // determine element of the list #ifdef USE_LIBRARY objfile = change_ext(file, "o"); // make obj-filename #else objfile = "./o/" + change_ext(file, "o"); // make obj-filename #endif if (objfile younger file) // objfile is younger { files -= (list)file; // remove the file from the list i--; // reduce i to test the next } } return (files); } /* parser.im */ void parser() { chdir("parser/gramspec"); system("grambuild"); chdir(".."); if ( exists("grammar") && "grammar" younger "parser.cc" ) // new parser needed { exec("bison++", "-d", "-o", "parser.cc", "grammar"); printf("Note: the compilation of parser.cc may produce " "several compiler warnings.\n"); } chdir(".."); } /* scanner.im */ void scanner() { chdir("scanner"); if ( // new lexer needed exists("lexer") && ( "lexer" younger "yylex.cc" || "../parser/parser.h" younger "yylex.cc" ) ) { exec("flex", #ifdef INTERACTIVE "-I", #endif "-oyylex.cc", "lexer"); printf("Note: the compilation of yylex.cc may produce " "several compiler warnings.\n"); } chdir(".."); } /* A L T E R E D . I M */ list altered(list files, string target) { int i; string file; for (i = 0; i < sizeof(files); i++) // try all elements of the list { file = element(i, files); // use element i of the list if (file older target) // a file is older than the target { files -= (list)file; // remove the file from the list i--; // reduce i to inspect the next } // file of the list } return (files); // return the new list } /* F I L E L I S T . I M */ list file_list(string type, string library) { list files; files = makelist(type); // make all files of certain type #ifdef USE_LIBRARY files = altered(files, library); // keep all files newer than lib. #endif files = objfiles(files); // remove if younger .obj exist return (files); } /* L I N K . I M */ void link(string library, string exe) { #ifndef RELINK if ( relink // new library, new main.obj || !exists(exe) // final program doesn't exist ) #endif { printf("\n"); exec(COMPILER, "-o", exe, #ifdef USE_LIBRARY "-l" + library, #else ofiles, #endif libs, "-L.", libpath, lopt #ifndef GDB , "-s" #endif ); printf("ok: ", exe, "\n"); } } /* C C O M P I L E . I M */ void c_compile(list cfiles) { string nextfile; int i; #ifndef USE_LIBRARY if (!exists("o")) system("mkdir o"); #endif if (sizeof(cfiles)) // files to compile ? { printf("\ncompiling: ", current, "\n\n"); // compile all files separately for (i = 0; nextfile = element(i, cfiles); i++) { #ifdef USE_LIBRARY exec(COMPILER, "-c " COPT + " " + copt + " " + nextfile); #else exec(COMPILER, "-c -o o/" + change_ext(nextfile, "o") + " " COPT + " " + copt + " " + nextfile); #endif } relink = 1; printf("\n"); } printf("ok: ", current, "\n"); } /* U P D A T E L I . I M */ void updatelib(string library) { list arlist, objlist; string to, from; objlist = makelist("*.o"); if (!sizeof(objlist)) return; printf("\n"); relink = 1; exec("ar", "rvs", library, "*.o"); exec("rm", "*.o"); printf("\n"); } void prefix_class(string class_id) { list o_files; string o_file; int i; o_files = makelist("*.o"); for (i = 0; o_file = element(i, o_files); i++) exec("mv", o_file, class_id + o_file); } /* S T D C P P . I M */ void std_cpp(string library) { list cfiles; cfiles = file_list(wild, library); // make list of all cpp-files c_compile(cfiles); // compile cpp-files } /* C P P M A K E . C CPP files are processed by stdmake. Arguments of CPPMAKE: cpp_make( string mainfile, : name of the main .cpp file, or "" for library maintenance string library, : name of the local library to use/create (without lib prefix, .a suffix if main is given here, libmain.a is created) string exe, : (path) name of the exe file to create ) Both mainfile and library MUST be in the current directory */ void cpp_make(string mainfile, string library, string exe) { int n, index; list classes; string cwd; #ifdef BISON++ CLASSES += "parser "; if (exists("parser")) // subdir parser exists parser(); #endif #ifdef FLEX++ CLASSES += "scanner "; if (exists("scanner")) // subdir scannerexists scanner(); #endif setClasses(); // remaining classes cwd = chdir("."); ofiles = "o/*.o"; // std set of o-files classes = strtok(CLASSES, " "); // list of classes if (n = sizeof(classes)) ofiles += " */o/*.o"; // set ofiles for no LIBRARY use wild = sources; // make library name libxxxa = chdir(".") + "lib" + library + ".a"; // first process all classes for (index = 0; index < n; index++) { current = element(index, classes); // next class to process chdir(current); // change to directory current = "subdir " + current; std_cpp (libxxxa); // compile all files chdir( cwd); // go back to parent dir } current = "auxiliary " + wild + " files"; std_cpp (libxxxa); // compile all files in current dir for (index = 0; index < n; index++) { current = element(index, classes); // determine class name chdir( current); // chdir to a class directory. #ifdef USE_LIBRARY prefix_class((string)index); // prefix class-number for .o files updatelib(libxxxa); #endif chdir(cwd); // go back to parent dir } current = ""; // no class anymore #ifdef USE_LIBRARY updatelib(libxxxa); // update lib in current dir #endif if (mainfile != "") // mainfile -> do link { link(library, exe); printf ( "\nProgram construction completed.\n" "\n" ); } } /* S E T L I B S . I M */ void setlibs() { int n, index; list cut; cut = strtok(LIBS, " "); // cut op libraries n = sizeof(cut); for (index = 0; index < n; index++) libs += " -l" + element(index, cut); #ifdef FLEX++ libs += " -lfl"; #endif cut = strtok(LIBPATH, " "); // cut up the paths n = sizeof(cut); for (index = 0; index < n; index++) libpath += " -L" + element(index, cut); } void main() { echo(ECHO_REQUEST); sources = "*.cc"; setlibs(); #ifdef GDB copt = "-g"; #endif #ifdef PROGRAM cpp_make ( "fork.cc", // program source "fork", // program library "fork" // binary program ); #else cpp_make ( "", "fork", // program library "" ); #endif } c++-annotations-12.5.0/yo/concrete/fork2/opipe/0000755000175000017500000000000014624637124020067 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fork2/opipe/opipe.ih0000664000175000017500000000007614624637127021535 0ustar frankfrank#include "opipe.h" using namespace FBB; using namespace std; c++-annotations-12.5.0/yo/concrete/fork2/opipe/opipe.cc0000664000175000017500000000021514624637131021510 0ustar frankfrank#include "opipe.ih" OPipe::OPipe(size_t size) : Pipe(), OFdNStreambuf(Pipe::d_fd[READ], size == 0 ? 1 : size), ostream(this) {} c++-annotations-12.5.0/yo/concrete/fork2/opipe/opipe.h0000664000175000017500000000067414624637127021370 0ustar frankfrank#ifndef INCLUDED_OPIPE_H_ #define INCLUDED_OPIPE_H_ #ifndef INCLUDED_PIPE_H_ #include "../pipe/pipe.h" #endif #ifndef INCLUDED_OFDNSTREAMBUF_H_ #include "../ofdnstreambuf/ofdnstreambuf.h" #endif #ifndef INCLUDED_OSTREAM_ #include #define INCLUDED_OSTREAM_ #endif namespace FBB { class OPipe: public Pipe, private OFdNStreambuf, public std::ostream { public: OPipe(size_t size = 500); }; } #endif c++-annotations-12.5.0/yo/concrete/fork2/ifdnstreambuf/0000755000175000017500000000000014624637124021604 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fork2/ifdnstreambuf/open.cc0000664000175000017500000000031214624637131023050 0ustar frankfrank#include "ifdnstreambuf.ih" void IFdNStreambuf::open(int fd, size_t n) { d_fd = fd; d_n = (n == 0) ? 1 : n; d_buffer = new char[d_n]; setg(d_buffer, d_buffer + d_n, d_buffer + d_n); } c++-annotations-12.5.0/yo/concrete/fork2/ifdnstreambuf/xsgetn.cc0000664000175000017500000000072014624637131023422 0ustar frankfrank#include "ifdnstreambuf.ih" std::streamsize IFdNStreambuf::xsgetn(char *dest, std::streamsize n) { int nread = 0; while (n) { if (!in_avail()) { if (underflow() == EOF) break; } int avail = in_avail(); if (avail > n) avail = n; memcpy(dest + nread, gptr(), avail); gbump(avail); nread += avail; n -= avail; } return nread; } c++-annotations-12.5.0/yo/concrete/fork2/ifdnstreambuf/ifdnstreambuf.ih0000664000175000017500000000013114624637127024757 0ustar frankfrank#include "ifdnstreambuf.h" #include #include using namespace FBB; c++-annotations-12.5.0/yo/concrete/fork2/ifdnstreambuf/ifdnstreambuf.h0000664000175000017500000000163014624637127024613 0ustar frankfrank#ifndef INCLUDED_IFDNSTREAMBUF_H_ #define INCLUDED_IFDNSTREAMBUF_H_ #ifndef INCLUDED_STREAMBUF_ #include #define INCLUDED_STREAMBUF_ #endif namespace FBB { class IFdNStreambuf: public std::streambuf { private: int d_fd; size_t d_n; char* d_buffer; public: IFdNStreambuf() : d_n(0), d_buffer(0) {} IFdNStreambuf(int fd, size_t n = 1) { open(fd, n); } ~IFdNStreambuf(); void open(int xfd, size_t n = 1); int underflow(); std::streamsize xsgetn(char *dest, std::streamsize n); private: IFdNStreambuf(IFdNStreambuf const &other); // NI IFdNStreambuf &operator=(IFdNStreambuf const &other); // NI }; } #endif c++-annotations-12.5.0/yo/concrete/fork2/ifdnstreambuf/destructor.cc0000664000175000017500000000021514624637131024307 0ustar frankfrank#include "ifdnstreambuf.ih" IFdNStreambuf::~IFdNStreambuf() { if (d_buffer) { close(d_fd); delete d_buffer; } } c++-annotations-12.5.0/yo/concrete/fork2/ifdnstreambuf/underflow.cc0000664000175000017500000000045014624637131024117 0ustar frankfrank#include "ifdnstreambuf.ih" int IFdNStreambuf::underflow() { if (gptr() < egptr()) return *gptr(); int nread = read(d_fd, d_buffer, d_n); if (nread <= 0) return EOF; setg(d_buffer, d_buffer, d_buffer + nread); return static_cast(*gptr()); } c++-annotations-12.5.0/yo/concrete/fork2/fork/0000755000175000017500000000000014624637124017714 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fork2/fork/fork.h0000664000175000017500000000136214624637127021035 0ustar frankfrank#ifndef INCLUDED_FORK_H_ #define INCLUDED_FORK_H_ namespace FBB { class Redirector; class ChildProcess; class ParentProcess; class Fork { protected: Redirector &d_redirector; ChildProcess &d_child; ParentProcess &d_parent; public: Fork(Redirector &redirector, ChildProcess &child, ParentProcess &parent) : d_redirector(redirector), d_child(child), d_parent(parent) {} void fork() const; private: Fork(Fork const &other); // NI Fork &operator=(Fork const &other); // NI }; } #endif c++-annotations-12.5.0/yo/concrete/fork2/fork/fork.ih0000664000175000017500000000070314624637127021204 0ustar frankfrank#include "fork.h" #ifndef INCLUDED_CHILDPROCESS_H_ #include "../childprocess/childprocess.h" #endif #ifndef INCLUDED_REDIRECTOR_H_ #include "../redirector/redirector.h" #endif #ifndef INCLUDED_PARENTPROCESS_H_ #include "../parentprocess/parentprocess.h" #endif #ifndef INCLUDED_TYPES_H_ #include #define INCLUDED_TYPES_H_ #endif #ifndef INCLUDED_UNISTD_H_ #include #define INCLUDED_UNISTD_H_ #endif using namespace FBB; c++-annotations-12.5.0/yo/concrete/fork2/fork/forkfork.cc0000664000175000017500000000064414624637131022052 0ustar frankfrank#include "fork.ih" void Fork::fork() const { int pid = ::fork(); if (pid == 0) // childprocess has pid == 0 { d_redirector.childRedirections(); d_child.run(); } d_redirector.parentRedirections(); d_parent.run(pid, d_redirector.readChildCout(), d_redirector.readChildCerr(), d_redirector.writeChildCin()); } c++-annotations-12.5.0/yo/concrete/fork2/childprocess/0000755000175000017500000000000014624637124021435 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fork2/childprocess/childprocess.ih0000664000175000017500000000017714624637127024453 0ustar frankfrank#include "childprocess.h" #ifndef INCLUDED_CSTDLIB_ #include #define INCLUDED_CSTDLIB_ #endif using namespace FBB; c++-annotations-12.5.0/yo/concrete/fork2/childprocess/run.cc0000664000175000017500000000022014624637131022542 0ustar frankfrank#include "childprocess.ih" void ChildProcess::run() { executeChildProcess(); exit(-1); // doProcess itself should stop } c++-annotations-12.5.0/yo/concrete/fork2/childprocess/childprocess.h0000664000175000017500000000055614624637127024303 0ustar frankfrank#ifndef INCLUDED_CHILDPROCESS_H_ #define INCLUDED_CHILDPROCESS_H_ namespace FBB { class ChildProcess { public: virtual ~ChildProcess() {} void run(); protected: // implemented in derived classes virtual void executeChildProcess() = 0; }; } #endif c++-annotations-12.5.0/yo/concrete/fork2/pipe/0000755000175000017500000000000014624637124017710 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fork2/pipe/readvia.cc0000664000175000017500000000016514624637131021634 0ustar frankfrank#include "pipe.ih" void Pipe::readVia(int fd) { close(d_fd[WRITE]); dup(READ, fd); close(d_fd[READ]); } c++-annotations-12.5.0/yo/concrete/fork2/pipe/writevia2.cc0000664000175000017500000000027414624637131022136 0ustar frankfrank#include "pipe.ih" void Pipe::writeVia(int const *fd, size_t n) { close(d_fd[READ]); for (size_t idx = 0; idx < n; idx++) dup(WRITE, fd[idx]); close(d_fd[WRITE]); } c++-annotations-12.5.0/yo/concrete/fork2/pipe/pipe.cc0000664000175000017500000000012314624637131021150 0ustar frankfrank#include "pipe.ih" Pipe::Pipe() { if (pipe(d_fd)) throw bad_pipe(); } c++-annotations-12.5.0/yo/concrete/fork2/pipe/pipe.ih0000664000175000017500000000017214624637127021174 0ustar frankfrank#include "pipe.h" #ifndef INCLUDED_UNISTD_H_ #include #define INCLUDED_UNISTD_H_ #endif using namespace FBB; c++-annotations-12.5.0/yo/concrete/fork2/pipe/dup.cc0000664000175000017500000000017214624637131021007 0ustar frankfrank#include "pipe.ih" void Pipe::dup(RW rw, int fd) { if (dup2(d_fd[rw], fd) < 0) throw redirection_failed(); } c++-annotations-12.5.0/yo/concrete/fork2/pipe/writevia.cc0000664000175000017500000000016714624637131022055 0ustar frankfrank#include "pipe.ih" void Pipe::writeVia(int fd) { close(d_fd[READ]); dup(WRITE, fd); close(d_fd[WRITE]); } c++-annotations-12.5.0/yo/concrete/fork2/pipe/readvia2.cc0000664000175000017500000000027214624637131021715 0ustar frankfrank#include "pipe.ih" void Pipe::readVia(int const *fd, size_t n) { close(d_fd[WRITE]); for (size_t idx = 0; idx < n; idx++) dup(READ, fd[idx]); close(d_fd[READ]); } c++-annotations-12.5.0/yo/concrete/fork2/pipe/pipe.h0000664000175000017500000000313514624637127021025 0ustar frankfrank#ifndef INCLUDED_PIPE_H_ #define INCLUDED_PIPE_H_ #include namespace FBB { class Pipe { protected: int d_fd[2]; public: enum bad_pipe {}; enum redirection_failed {}; Pipe(); Pipe(int socket) { d_fd[READ] = socket; d_fd[WRITE] = socket; } Pipe(int const *fd) { d_fd[READ] = fd[READ]; d_fd[WRITE] = fd[WRITE]; } // readVia(): set up redirection from d_fd[READ] to the given // filedescriptor(s): reading from d_fd[READ] // is done via the filedescriptor(s) void readVia(int filedescriptor); // not tested: void readVia(int const *filedescriptor, size_t n); // writeVia(): set up redirection from d_fd[WRITE] to the given // filedescriptor(s): writing to d_fd[WRITE] // is done via the filedescriptor(s) void writeVia(int filedescriptor); void writeVia(int const *filedescriptor, size_t n = 2); int readFd() { return d_fd[READ]; } int writeFd() { return d_fd[WRITE]; } protected: enum RW { READ, WRITE }; private: void dup(RW rw, int fd); Pipe(Pipe const &other); // NI Pipe &operator=(Pipe const &other); // NI }; } #endif c++-annotations-12.5.0/yo/concrete/fork2/pipe/driver/0000755000175000017500000000000014624637124021203 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fork2/pipe/driver/build0000755000175000017500000003020414466730207022227 0ustar frankfrank#!/usr/bin/icmake -t. // script generated by the C++ icmake script version 1.62 /* Configurable defines for the build script: CLASSES: string of directory-names under which sources of classes are found. E.g., CLASSES = "class1 class2" All class-names must be stored in one string. If classes are removed from the CLASSES definition or if the names in the CLASSES definition are reordered, the compilation should start again from scratch. */ string CLASSES; void setClasses() { // ADD ADDITIONAL DIRECTORIES CONTAINING SOURCES OF CLASSES HERE // Use the construction `CLASSES += "classname1 classname2";' etc. CLASSES += " "; } /* COMPILER: "g++" for C++ sources. Do not change this, unless you're sure you want something else. COPT: C-options used by COMPILER ECHO_REQUEST: ON (default) if command echoing is wanted, otherwise: set to OFF GDB: define if gdb-symbolic debug information is wanted (not defined by default) LIBS: Extra libraries used for linking LIBPATH: Extra library-searchpaths used for linking USE_LIBRARY: define this if you want a library for the object modules. Undefined by default: so NO LIBRARY IS USED. PROGRAM: define if a program is to be built. If not defined, library maintenance is assumed. (default: defined) RELINK: Defined by default, causing a program to be relinked every time the script is called. Do not define it if relinking should only occur if a source is compiled. No effect for library maintenance. Current values: */ #define COMPILER "g++" // COPT: the set of C-options #define COPT "--std=c++11 -Wall" #define ECHO_REQUEST ON // #define GDB // Extra libraries required. Remove lib and .a from the library names. // E.g., #define LIBS "m Xt" to link libm.a and libXt.a explicitly // Specify libs from the most specific to the most general one. #define LIBS "fork" // Extra library-paths required. // E.g., #define LIBPATH "/some/path /some/other/path" to search these paths // apart from the default paths #define LIBPATH "../.." // uncomment if you WANT to use a library // #define USE_LIBRARY #define PROGRAM #define RELINK // DO NOT ALTER THINGS BELOW THIS LINE string // contain options for libs, // extra libs, e.g., "-lrss -licce" libpath, // extra lib-paths, eg, "-L../rss" copt, lopt, libxxxa; // expanded lib-name int relink; // internally used: != 0 to relink string ofiles, // wildcards for o-files sources, // sources to be used wild, // wildcard of extension current; // contains name of current dir. /* O B J F I L E S . I M */ list objfiles(list files) { string file, objfile; int i; for (i = 0; i < sizeof(files); i++) { file = element(i, files); // determine element of the list #ifdef USE_LIBRARY objfile = change_ext(file, "o"); // make obj-filename #else objfile = "./o/" + change_ext(file, "o"); // make obj-filename #endif if (objfile younger file) // objfile is younger { files -= (list)file; // remove the file from the list i--; // reduce i to test the next } } return (files); } /* parser.im */ void parser() { chdir("parser/gramspec"); system("grambuild"); chdir(".."); if ( exists("grammar") && "grammar" younger "parser.cc" ) // new parser needed { exec("bison++", "-d", "-o", "parser.cc", "grammar"); printf("Note: the compilation of parser.cc may produce " "several compiler warnings.\n"); } chdir(".."); } /* scanner.im */ void scanner() { chdir("scanner"); if ( // new lexer needed exists("lexer") && ( "lexer" younger "yylex.cc" || "../parser/parser.h" younger "yylex.cc" ) ) { exec("flex", #ifdef INTERACTIVE "-I", #endif "-oyylex.cc", "lexer"); printf("Note: the compilation of yylex.cc may produce " "several compiler warnings.\n"); } chdir(".."); } /* A L T E R E D . I M */ list altered(list files, string target) { int i; string file; for (i = 0; i < sizeof(files); i++) // try all elements of the list { file = element(i, files); // use element i of the list if (file older target) // a file is older than the target { files -= (list)file; // remove the file from the list i--; // reduce i to inspect the next } // file of the list } return (files); // return the new list } /* F I L E L I S T . I M */ list file_list(string type, string library) { list files; files = makelist(type); // make all files of certain type #ifdef USE_LIBRARY files = altered(files, library); // keep all files newer than lib. #endif files = objfiles(files); // remove if younger .obj exist return (files); } /* L I N K . I M */ void link(string library, string exe) { #ifndef RELINK if ( relink // new library, new main.obj || !exists(exe) // final program doesn't exist ) #endif { printf("\n"); exec(COMPILER, "-o", exe, #ifdef USE_LIBRARY "-l" + library, #else ofiles, #endif libs, "-L.", libpath, lopt #ifndef GDB , "-s" #endif ); printf("ok: ", exe, "\n"); } } /* C C O M P I L E . I M */ void c_compile(list cfiles) { string nextfile; int i; #ifndef USE_LIBRARY if (!exists("o")) system("mkdir o"); #endif if (sizeof(cfiles)) // files to compile ? { printf("\ncompiling: ", current, "\n\n"); // compile all files separately for (i = 0; nextfile = element(i, cfiles); i++) { #ifdef USE_LIBRARY exec(COMPILER, "-c " COPT + " " + copt + " " + nextfile); #else exec(COMPILER, "-c -o o/" + change_ext(nextfile, "o") + " " COPT + " " + copt + " " + nextfile); #endif } relink = 1; printf("\n"); } printf("ok: ", current, "\n"); } /* U P D A T E L I . I M */ void updatelib(string library) { list arlist, objlist; string to, from; objlist = makelist("*.o"); if (!sizeof(objlist)) return; printf("\n"); relink = 1; exec("ar", "rvs", library, "*.o"); exec("rm", "*.o"); printf("\n"); } void prefix_class(string class_id) { list o_files; string o_file; int i; o_files = makelist("*.o"); for (i = 0; o_file = element(i, o_files); i++) exec("mv", o_file, class_id + o_file); } /* S T D C P P . I M */ void std_cpp(string library) { list cfiles; cfiles = file_list(wild, library); // make list of all cpp-files c_compile(cfiles); // compile cpp-files } /* C P P M A K E . C CPP files are processed by stdmake. Arguments of CPPMAKE: cpp_make( string mainfile, : name of the main .cpp file, or "" for library maintenance string library, : name of the local library to use/create (without lib prefix, .a suffix if main is given here, libmain.a is created) string exe, : (path) name of the exe file to create ) Both mainfile and library MUST be in the current directory */ void cpp_make(string mainfile, string library, string exe) { int n, index; list classes; string cwd; #ifdef BISON++ CLASSES += "parser "; if (exists("parser")) // subdir parser exists parser(); #endif #ifdef FLEX++ CLASSES += "scanner "; if (exists("scanner")) // subdir scannerexists scanner(); #endif setClasses(); // remaining classes cwd = chdir("."); ofiles = "o/*.o"; // std set of o-files classes = strtok(CLASSES, " "); // list of classes if (n = sizeof(classes)) ofiles += " */o/*.o"; // set ofiles for no LIBRARY use wild = sources; // make library name libxxxa = chdir(".") + "lib" + library + ".a"; // first process all classes for (index = 0; index < n; index++) { current = element(index, classes); // next class to process chdir(current); // change to directory current = "subdir " + current; std_cpp (libxxxa); // compile all files chdir( cwd); // go back to parent dir } current = "auxiliary " + wild + " files"; std_cpp (libxxxa); // compile all files in current dir for (index = 0; index < n; index++) { current = element(index, classes); // determine class name chdir( current); // chdir to a class directory. #ifdef USE_LIBRARY prefix_class((string)index); // prefix class-number for .o files updatelib(libxxxa); #endif chdir(cwd); // go back to parent dir } current = ""; // no class anymore #ifdef USE_LIBRARY updatelib(libxxxa); // update lib in current dir #endif if (mainfile != "") // mainfile -> do link { link(library, exe); printf ( "\nProgram construction completed.\n" "\n" ); } } /* S E T L I B S . I M */ void setlibs() { int n, index; list cut; cut = strtok(LIBS, " "); // cut op libraries n = sizeof(cut); for (index = 0; index < n; index++) libs += " -l" + element(index, cut); #ifdef FLEX++ libs += " -lfl"; #endif cut = strtok(LIBPATH, " "); // cut up the paths n = sizeof(cut); for (index = 0; index < n; index++) libpath += " -L" + element(index, cut); } void main() { echo(ECHO_REQUEST); sources = "*.cc"; setlibs(); #ifdef GDB copt = "-g"; #endif #ifdef PROGRAM cpp_make ( "driver.cc", // program source "driver", // program library "driver" // binary program ); #else cpp_make ( "", "driver", // program library "" ); #endif } c++-annotations-12.5.0/yo/concrete/fork2/pipe/driver/driver.cc0000664000175000017500000000174714624637131023016 0ustar frankfrank/* driver.cc */ #include "../pipe.h" #include #include #include #include #include using namespace std; using namespace FBB; int main(int argc, char **argv) { Pipe p; // construct a pipe cout << "Read file descriptor: " << p.readFd() << '\n'; cout << "Write file descriptor: " << p.writeFd() << '\n'; int pid = fork(); if (pid == -1) return 1; if (!pid) //child { p.readVia(STDIN_FILENO); // read what goes into the pipe from cin string s; getline(cin, s); cout << "Got: " << s << '\n'; getline(cin, s); cout << "Got: " << s << '\n'; return 0; } int stdfd[] = {STDOUT_FILENO, STDERR_FILENO}; p.writeVia(stdfd); // write to the pipe via cout cout << "first line" << '\n'; cerr << "second line" << '\n'; waitpid(pid, 0, 0); } c++-annotations-12.5.0/yo/concrete/fork2/pipe/driver/driver.h0000664000175000017500000000053114624637127022653 0ustar frankfrank// driver.h #ifndef H_driver_ #define H_driver_ /* $Id: driver.h 2 2003-05-27 19:11:03Z frank $ $Log$ Revision 1.1 2003/05/27 19:11:04 frank Initial revision */ //#include //#include //#include //#include //#include //using namespace std; #endif c++-annotations-12.5.0/yo/concrete/fork2/ofdnstreambuf/0000755000175000017500000000000014624637124021612 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fork2/ofdnstreambuf/ofdnstreambuf.ih0000664000175000017500000000013114624637127024773 0ustar frankfrank#include "ofdnstreambuf.h" #include #include using namespace FBB; c++-annotations-12.5.0/yo/concrete/fork2/ofdnstreambuf/overflow.cc0000664000175000017500000000024314624637131023763 0ustar frankfrank#include "ofdnstreambuf.ih" int OFdNStreambuf::overflow(int c) { sync(); if (c != EOF) { *pptr() = c; pbump(1); } return c; } c++-annotations-12.5.0/yo/concrete/fork2/ofdnstreambuf/open.cc0000664000175000017500000000027214624637131023063 0ustar frankfrank#include "ofdnstreambuf.ih" void OFdNStreambuf::open(int fd, size_t n) { d_fd = fd; d_n = (n == 0) ? 1 : n; d_buffer = new char[d_n]; setp(d_buffer, d_buffer + d_n); } c++-annotations-12.5.0/yo/concrete/fork2/ofdnstreambuf/sync.cc0000664000175000017500000000031014624637131023067 0ustar frankfrank#include "ofdnstreambuf.ih" int OFdNStreambuf::sync() { if (pptr() > pbase()) { write(d_fd, d_buffer, pptr() - pbase()); setp(d_buffer, d_buffer + d_n); } return 0; } c++-annotations-12.5.0/yo/concrete/fork2/ofdnstreambuf/destructor.cc0000664000175000017500000000021014624637131024310 0ustar frankfrank#include "ofdnstreambuf.ih" OFdNStreambuf::~OFdNStreambuf() { if (d_buffer) { sync(); delete d_buffer; } } c++-annotations-12.5.0/yo/concrete/fork2/ofdnstreambuf/ofdnstreambuf.h0000664000175000017500000000156014624637127024631 0ustar frankfrank#ifndef INCLUDED_OFDNSTREAMBUF_H_ #define INCLUDED_OFDNSTREAMBUF_H_ #ifndef INCLUDED_STREAMBUF_ #include #define INCLUDED_STREAMBUF_ #endif namespace FBB { class OFdNStreambuf: public std::streambuf { private: size_t d_n; int d_fd; char *d_buffer; public: OFdNStreambuf() : d_n(0), d_buffer(0) {} OFdNStreambuf(int fd, size_t n = 1) { open(fd, n); } ~OFdNStreambuf(); void open(int fd, size_t n = 1); int sync(); int overflow(int c); private: OFdNStreambuf(OFdNStreambuf const &other); // NI OFdNStreambuf &operator=(OFdNStreambuf const &other); // NI }; } #endif c++-annotations-12.5.0/yo/concrete/fork2/cinredirector/0000755000175000017500000000000014624637124021607 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fork2/cinredirector/cinredirector.h0000664000175000017500000000106014624637127024616 0ustar frankfrank#ifndef INCLUDED_CINREDIRECTOR_H_ #define INCLUDED_CINREDIRECTOR_H_ #ifndef INCLUDED_REDIRECTOR_H_ #include "../redirector/redirector.h" #endif #ifndef INCLUDED_OPIPE_H_ #include "../opipe/opipe.h" #endif namespace FBB { class CinRedirector: public Redirector { private: OPipe d_cinPipe; public: virtual void childRedirections(); virtual void parentRedirections(); virtual std::ostream &writeChildCin() { return d_cinPipe; } }; } #endif c++-annotations-12.5.0/yo/concrete/fork2/cinredirector/childredirections.cc0000664000175000017500000000023114624637131025610 0ustar frankfrank#include "cinredirector.ih" void CinRedirector::childRedirections() { // redirect STDIN_FILENO to the pipe: d_cinPipe.readVia(STDIN_FILENO); } c++-annotations-12.5.0/yo/concrete/fork2/cinredirector/parentredirections.cc0000664000175000017500000000015114624637131026017 0ustar frankfrank#include "cinredirector.ih" void CinRedirector::parentRedirections() { close(d_cinPipe.readFd()); } c++-annotations-12.5.0/yo/concrete/fork2/cinredirector/cinredirector.ih0000664000175000017500000000020314624637127024765 0ustar frankfrank#include "cinredirector.h" #ifndef INCLUDED_UNISTD_H_ #include #define INCLUDED_UNISTD_H_ #endif using namespace FBB; c++-annotations-12.5.0/yo/concrete/fork2/redirector/0000755000175000017500000000000014624637123021114 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fork2/redirector/redirector.h0000664000175000017500000000174214624637127023441 0ustar frankfrank#ifndef INCLUDED_REDIRECTOR_H_ #define INCLUDED_REDIRECTOR_H_ #ifndef INCLUDED_IOSFWD_ #include #define INCLUDED_IOSFWD_ #endif #ifndef INCLUDED_IOSTREAM_ #include #define INCLUDED_IOSTREAM_ #endif namespace FBB { class Redirector { public: enum { READ, WRITE }; virtual ~Redirector() {} // sets up redirections in the child virtual void childRedirections() {} // sets up redirections in the parent virtual void parentRedirections() {} virtual std::ostream &writeChildCin() { return std::cout; } virtual std::istream &readChildCout() { return std::cin; } virtual std::istream &readChildCerr() { return std::cin; } }; } #endif c++-annotations-12.5.0/yo/concrete/fork2/ipipe/0000755000175000017500000000000014624637123020060 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/fork2/ipipe/ipipe.h0000664000175000017500000000150514624637127021346 0ustar frankfrank#ifndef INCLUDED_IPIPE_H_ #define INCLUDED_IPIPE_H_ #ifndef INCLUDED_PIPE_H_ #include "../pipe/pipe.h" #endif #ifndef INCLUDED_ISTREAM_ #include #define INCLUDED_ISTREAM_ #endif namespace FBB { class IPipe: virtual public Pipe { private: IfdNstreambuf d_ibuf; std::istream d_istr; public: IPipe(size_t size = 500) : Pipe(socket), d_ibuf(d_fd[READ], size == 0 ? 1 : size), d_istr(&d_ibuf) {} IPipe(int socket, size_t size) : Pipe(socket), d_ibuf(d_fd[READ], size == 0 ? 1 : size), d_istr(&d_ibuf) {} istream &istream() { return d_istr; } }; } #endif c++-annotations-12.5.0/yo/concrete/ranger.yo0000644000175000017500000001143114466730207017557 0ustar frankfrankThe standard i(range-based for-loop) requires for its range-specificiation an array, an initializer list, or an iterator range as offered by, e.g., containers (through their tt(begin) and tt(end) members). Ranges defined by a pointer pair or by a subrange defined by iterator expressions cannot currently be used in combination with range-based for-loops. The ti(Ranger) class template developed in this section defines ranges that can be used with range-based for-loops. tt(Ranger) extends the applicability of range-based for-loops by turning pointer pairs,, an initial pointer or iterator and a pointer count, or a pair of iterators into a range that can be used by range-based for-loops. The tt(Ranger) class template can also be used to process a pair of reverse iterators, normally not supported by range-based for-loops. The tt(Ranger) class template requires but one template type parameter: tt(Iterator), representing an iterator or pointer type reaching the data when dereferenced. In practical applications users don't have to specify tt(Ranger)'s template type. The function template tt(ranger) deduces the required tt(Iterator) type and returns the appropriate tt(Ranger) object. The tt(ranger) function template can be used in various ways: itemization( itt(Ranger ranger(Iterator const &begin, Iterator const &end)) this function template returns a tt(Ranger) object for the (sub)range defined by two (reverse) iterators. Its definition is: verb(template Ranger ranger(Iter &&begin, Iter &&end) { return Ranger{ begin, end }; }) itt(Ranger ranger(Iterator const &begin, size_t count)) this function template returns a tt(Ranger) object for the (sub)range defined by the (reverse) iterator range tt(begin) and tt(begin + count). Its definition is: verb(template Ranger ranger(Data *begin, Data *end) { return Ranger{ begin, end }; }) itt(Ranger ranger(Data *begin, Data *end)) this function template returns a tt(Ranger) object for the (sub)range defined by the two pointers tt(begin) and tt(end). Its definition is: verb(template Ranger ranger(Iter &&begin, size_t count) { return Ranger{ begin, begin + count }; }) itt(Ranger ranger(Data *begin, size_t count)) this function template returns a tt(Ranger) object for the (sub)range defined by the two pointers tt(begin) and tt(begin + count). Its definition is: verb(template Ranger ranger(Data *begin, size_t count) { return Ranger{ begin, begin + count}; }) ) The tt(Ranger) class template itself offers a constructor expecting two tt(Iterator const &) parameters, where tt(Iterator) is tt(Ranger)'s template type parameter. Although named 'Iterator' it can also be a pointer to some data type (e.g., tt(std::string *)). The class only needs two members, tt(begin) and tt(end), since these are the only members called by range-based for-loops. These members can be tt(const) members, returning tt(Iterator const) references. This also is the required return type if tt(Iterator) itself was a pointer type (like tt(int *)). Since a `tt(Iterator const &)' does not imply that the dereferenced tt(Iterator) is immutable, the data to which the iterator returned by tt(begin()) can actually be modified, if tt(Iterator) unless tt(Iterator) is a tt(Type const *) or a tt(const_iterator) type. If reverse iterators are passed to tt(Ranger)'s constructor (the reversed begin iterator should be passed as tt(Ranger) constructor's first argument, the reversed end iterator as its second argument), then tt(Ranger)'s tt(begin) and tt(end) members return em(reverse iterators). Since the intended use of tt(Ranger) objects is to define a range for range-base for-loops, members like tt(rbegin) and tt(rend) were omitted from tt(Ranger)'s interface. Here is tt(Ranger)'s implementation (using in-class implementations for brevity): verb( template class Ranger { Iter d_begin; Iter d_end; public: Ranger(Iter const &begin, Iter const &end) : d_begin(begin), d_end(end) {} Iter const &begin() const { return d_begin; } Iter const &end() const { return d_end; } };) Using tt(ranger) is easy. Here is an example of a program displaying a program's command-line arguments using a range-based for-loop: verb( // insert all required declarations here int main(int argc, char **argv) { for (auto ptr: ranger(argv, argc)) cout << ptr << '\n'; }) c++-annotations-12.5.0/yo/concrete/pipes.yo0000644000175000017500000001076614466730207017433 0ustar frankfrank Redirection at the system level requires the use of em(file descriptor)hi(file descriptor), created by the ti(pipe) system call. When two processes want to communicate using such file descriptors, the following happens: itemization( it() The process constructs two em(associated file descriptors) using the tt(pipe) system call. One of the file descriptors is used for writing, the other file descriptor is used for reading. it() Forking takes place (i.e., the system tt(fork) function is called), duplicating the file descriptors. Now we have four file descriptors as the child process and the parent process both have their own copies of the two file descriptors created by tt(pipe). it() One process (say, the parent process) uses the file descriptors for em(reading). It should close its file descriptor intended for em(writing). it() The other process (say, the child process) uses the file descriptors for em(writing). It should therefore close its file descriptor intended for em(reading). it() All information written by the child process to the file descriptor intended for writing, can now be read by the parent process from the corresponding file descriptor intended for reading, thus establishing a communication channel between the child and the parent process. ) Though basically simple, errors may easily creep in. Functions of file descriptors available to the two processes (child or parent) may easily get mixed up. To prevent bookkeeping errors, the bookkeeping may be properly set up once, to be hidden thereafter inside a class like the tt(Pipe) class developed here. Let's have a look at its characteristics (before using functions like tt(pipe) and tt(dup) the compiler must have read the tthi(unistd.h) header file): itemization( it() The tt(pipe) system call expects a pointer to two tt(int) values, representing, respectively, the file descriptor used for reading and the file descriptor used for writing. To avoid confusion, the class tt(Pipe) defines an tt(enum) having values associating the indices of the array of 2-tt(int)s with symbolic constants. The two file descriptors themselves are stored in a data member tt(d_fd). Here is the initial section of the class's interface: verbinclude(//HEAD examples/pipe.h) it() The class only needs a default constructor. This constructor calls tt(pipe) to create a set of associated file descriptors used for accessing both ends of a pipe: verbinclude(//CONS examples/pipe.cc) it() The members tt(readOnly) and tt(readFrom) are used to configure the pipe's reading end. The latter function is used when using redirection. It is provided with an alternate file descriptor to be used for reading from the pipe. Usually this alternate file descriptor is ti(STDIN_FILENO), allowing tt(cin) to extract information from the pipe. The former function is merely used to configure the reading end of the pipe. It closes the matching writing end and returns a file descriptor that can be used to read from the pipe: verbinclude(//READ examples/pipe.cc) it() tt(writeOnly) and two tt(writtenBy) members are available to configure the writing end of a pipe. The former function is only used to configure the writing end of the pipe. It closes the reading end, and returns a file descriptor that can be used for writing to the pipe: verbinclude(//WRITE examples/pipe.cc) For the latter member two overloaded versions are available: itemization( itt(writtenBy(int fd)) is used to configure em(single) redirection, so that a specific file descriptor (usually ti(STDOUT_FILENO) or ti(STDERR_FILENO)) can be used to write to the pipe; itt((writtenBy(int const *fd, size_t n))) may be used to configure em(multiple) redirection, providing an array argument containing file descriptors. Information written to any of these file descriptors is actually written to the pipe. ) it() The class has one private data member, tt(redirect), used to set up redirection through the ti(dup2) system call. This function expects two file descriptors. The first file descriptor represents a file descriptor that can be used to access the device's information; the second file descriptor is an alternate file descriptor that may also be used to access the device's information. Here is tt(redirect)'s implementation: verbinclude(//REDIRECT examples/pipe.cc) ) Now that redirection can be configured easily using one or more tt(Pipe) objects, we'll use tt(Fork) and tt(Pipe) in various example programs. c++-annotations-12.5.0/yo/concrete/usingbison.yo0000644000175000017500000000506514466730207020467 0ustar frankfrankOnce an i(input language) exceeds a certain level of complexity, a emi(parser) is often used to control the complexity of the language. In this case, a emi(parser generator) can be used to generate the code verifying the input's grammatical correctness. The lexical scanner (preferably composed into the parser) provides chunks of the input, called hi(token)em(tokens). The parser then processes the series of tokens generated by the lexical scanner. Starting point when developing programs that use both parsers and scanners is the i(grammar). The grammar defines a em(set of tokens) that can be returned by the lexical scanner (called the emi(scanner) below). Finally, auxiliary code is provided to `fill in the blanks': the i(actions) performed by the parser and by the scanner are not normally specified literally in the grammar rules or lexical regular expressions, but should be implemented in em(member functions), called from the parser's rules or which are associated with the scanner's regular expressions. In the previous section we've seen an example of a bf(C++) class generated by ti(flexc++). In the current section we concentrate on the parser. The parser can be generated from a grammar specification file, processed by the program ti(bisonc++). The grammar specification file required by tt(bisonc++) is similar to the file processed by ti(bison) (or ti(bison++), tt(bisonc++)'s predecessor, written in the early nineties by hi(Coetmeur, A.) em(Alain Coetmeur)). In this section a program is developed converting em(infix expressions), where binary operators are written between their operands, to em(postfix expressions), where operators are written behind their operands. Also, the unary operator tt(-) is converted from its prefix notation to a postfix form. The unary tt(+) operator is ignored as it requires no further actions. In essence our little calculator is a micro compiler, transforming numeric expressions into assembly-like instructions. Our calculator recognizes a rather basic set of operators: multiplication, addition, parentheses, and the unary minus. We'll distinguish real numbers from integers, to illustrate a subtlety in bison-like grammar specifications. That's all. The purpose of this section is, after all, to illustrate the construction of a bf(C++) program that uses both a parser and a lexical scanner, rather than to construct a full-fledged calculator. In the coming sections we'll develop the grammar specification for tt(bisonc++). Then, the regular expressions for the scanner are specified. Following that, the final program is constructed. c++-annotations-12.5.0/yo/concrete/crtp.yo0000644000175000017500000000661614466730207017262 0ustar frankfrankWhen deriving classes from a class template tt(Binops), using the CRTP the operators are defined for arguments of the class tt(Binops): a base class receiving the derived class as its template argument. Thus the class tt(Binops) as well as the additional operators are defined, expecting tt(Binops) type of arguments: verb( template struct Binops { Derived &operator+=(Derived const &rhs) &; }; template Derived operator+(Binops const &lhs, Derived const &rhs) { return Derived{static_cast(lhs) } += rhs; } // analogous implementation for Binops &&lhs) This way, a class that derives from tt(Binops), and that provides an tt(operator+=) member which is bound to an rvalue reference object, suddenly also provides all other binary addition operators: verb( class Derived: public Binops { ... public: ... Derived &&operator+=(Derived const &rhs) && };) All, but one.... The operator that's not available is the compound addition operator, bound to an lvalue reference. As its function name is identical to the one in the class tt(Derived), it is not automatically visible at the user level. Although this problem can simply be solved by providing the class tt(Derived) with a tt(using Binops::operator+=) declaration, it is not a very attractive solution, as separate using declarations have to be provided for each binary operator that is implemented in the class tt(Derived). But a em(much) more attractive solution exists. A beautiful out-of-the-box solution, completely avoiding the hidden base class operator, was proposed by i(Wiebe-Marten Wijnja). Wiebe-Marten conjectured that tt(operator+=), bound to an lvalue reference could also very well be defined as a em(free) function. In that case no inheritance is used and therefore no function hiding occurs. Consequently, the tt(using) directive can be avoided. The implementation of this free tt(operator+=) function looks like this: verb( template Derived &operator+=(Binops &lhs, Derived const &rhs) { Derived tmp{ Derived{ static_cast(lhs) } += rhs }; tmp.swap(static_cast(lhs)); return static_cast(lhs); }) The flexibility of this design can be further augmented once we realize that the right-hand side operand doesn't have to be a tt(Derived) class object. Consider tt(operator<<): oftentimes shifts are bit-shifts, using a tt(size_t) to specify the number of bits to shift. In fact, the type of the right-hand side operand can completely be generalized by defining a second template type parameter, which is used to specify the right-hand side's operand type. It's up to the tt(Derived) class to specify the argument type of its tt(operator+=) (or any other binary compound operator), whereafter the compiler will deduce the types of the right-hand side operands for the remaining binary operators. Here is the final implementation of the free tt(operator+=) function: verb( template Derived &operator+=(Binops &lhs, Rhs const &rhs) { Derived tmp{ Derived{ static_cast(lhs) } += rhs }; tmp.swap(static_cast(lhs)); return static_cast(lhs); }) c++-annotations-12.5.0/yo/concrete/children.yo0000644000175000017500000000236014466730207020072 0ustar frankfrank The next step up the ladder is the construction of a child-process monitor. Here, the parent process is responsible for all its child processes, but it also must read their standard output. The user enters information at the standard input of the parent process. A simple emi(command language) is used for this: itemization( itt(start): this starts a new child process. The parent returns the child's ID (a number) to the user. The ID is thereupon be used to identify a particular child process; itt( text) sends ``tt(text)'' to the child process having ID tt(); itt(stop ) terminates the child process having ID tt(); itt(exit) terminates the parent as well as all its child processes. ) If a child process hasn't received text for some time it will complain by sending a message to the parent-process. Those messages are simply transmitted to the user by copying them to the standard output stream. A problem with programs like our monitor is that they allow emi(asynchronous input) from multiple sources. Input may appear at the standard input as well as at the input-sides of pipes. Also, multiple output channels are used. To handle situations like these, the ti(select) system call was developed. c++-annotations-12.5.0/yo/concrete/selectimpl.yo0000644000175000017500000001057614466730207020453 0ustar frankfrank Selector's member functions serve the following tasks: itemization( itht(Selector)(Selector()): the (default) constructor. It clears the read, write, and execute tt(fd_set) variables, and switches off the alarm. Except for tt(d_max), the remaining data members do not require specific initializations: verbinclude(//SELECTOR examples/selector.cc) itht(wait)(int wait()): this member em(blocks) until the em(alarm) times out or until activity is sensed at any of the file descriptors monitored by the tt(Selector) object. It throws an exception when the tt(select) system call itself fails: verbinclude(//WAIT examples/selector.cc) itht(nReady)(int nReady): this member function's return value is only defined when tt(wait) has returned. In that case it returns 0 for an alarm-timeout, -1 if tt(select) failed, and otherwise the number of file descriptors on which activity was sensed: verbinclude(//NREADY examples/selector.h) itht(readFd)(int readFd()): this member function's return value is also only defined after tt(wait) has returned. Its return value is -1 if no (more) input file descriptors are available. Otherwise the next file descriptor available for reading is returned: verbinclude(//READFD examples/selector.h) itht(writeFd)(int writeFd()): operating analogously to tt(readFd), it returns the next file descriptor to which output is written. It uses tt(d_writeidx) and tt(d_ret_read) and is implemented analogously to tt(readFd); itht(exceptFd)(int exceptFd()): operating analogously to tt(readFd), it returns the next exception file descriptor on which activity was sensed. It uses tt(d_except_idx) and tt(d_ret_except) and is implemented analogously to tt(readFd); itht(setAlarm)(void setAlarm(int sec, int usec = 0)): this member activates tt(Select)'s alarm facility. At least the number of seconds to wait for the alarm to go off must be specified. It simply assigns values to tt(d_alarm)'s fields. At the next tt(Select::wait) call, the alarm fires (i.e., tt(wait) returns with return value 0) once the configured alarm-interval has passed: verbinclude(//SETALARM examples/selector.h) itht(noAlarm)(void noAlarm()): this member switches off the alarm, by simply setting the alarm interval to a very long period: verbinclude(//NOALARM examples/selector.h) itht(addReadFd)(void addReadFd(int fd)): this member adds a file descriptor to the set of input file descriptors monitored by the tt(Selector) object. The member function tt(wait) returns once input is available at the indicated file descriptor: verbinclude(//ADDREAD examples/selector.h) itht(addWriteFd)(void addWriteFd(int fd)): this member adds a file descriptor to the set of output file descriptors monitored by the tt(Selector) object. The member function tt(wait) returns once output is available at the indicated file descriptor. Using tt(d_write), it is implemented analogously to tt(addReadFd); itht(addExceptFd)(void addExceptFd(int fd)): this member adds a file descriptor to the set of exception file descriptors to be monitored by the tt(Selector) object. The member function tt(wait) returns once activity is sensed at the indicated file descriptor. Using tt(d_except), it is implemented analogously to tt(addReadFd); itht(rmReadFd)(void rmReadFd(int fd)): this member removes a file descriptor from the set of input file descriptors monitored by the tt(Selector) object: verbinclude(//RMREAD examples/selector.h) itht(rmWriteFd)(void rmWriteFd(int fd)): this member removes a file descriptor from the set of output file descriptors monitored by the tt(Selector) object. Using tt(d_write), it is implemented analogously to tt(rmReadFd); itht(rmExceptFd)(void rmExceptFd(int fd)): this member removes a file descriptor from the set of exception file descriptors to be monitored by the tt(Selector) object. Using tt(d_except), it is implemented analogously to tt(rmReadFd); ) The class's remaining (two) members are support members, and should not be used by non-member functions. Therefore, they are declared in the class's tt(private) section: itemization( it() The member tt(addFd) adds a file descriptor to a tt(fd_set): verbinclude(//ADDFD examples/selector.cc) it() The member tt(checkSet) tests whether a file descriptor (tt(*index)) is found in a tt(fd_set): verbinclude(//CHECKSET examples/selector.cc) ) c++-annotations-12.5.0/yo/concrete/bisonflex.yo0000644000175000017500000001056414466730207020300 0ustar frankfrank The example discussed below digs into the peculiarities of using i(parser)- and i(scanner) generators generating bf(C++) sources. Once the input for a program exceeds a certain level of complexity, it becomes attractive to use scanner- and parser-generators generating the code which does the actual input recognition. The examples in this and subsequent sections assume that the reader knows how to use the i(scanner generator) ti(flex) and the i(parser generator) ti(bison). Both tt(bison) and tt(flex) are well documented elsewhere. The original predecessors of tt(bison) and tt(flex), called ti(yacc) and ti(lex) are described in several books, e.g. in hi(http://www.oreilly.com/catalog/lex) O'Reilly's book url(`lex & yacc')(http://www.oreilly.com/catalog/lex). Scanner- and parser generators are also available as free software. Both tt(bison) and tt(flex) are usually part of software distributions or they can be obtained from hi(ftp::/prep.ai.mit.edu/pub/non-gnu) tlurl(ftp://prep.ai.mit.edu/pub/non-gnu). tt(Flex) creates a tt(C++) class when ti(%option c++) is specified. For parser generators the program ti(bison) is available. In the early 90's em(Alain Coetmeur) (url(coetmeur@icdc.fr)(mailto:coetmeur@icdc.fr)) created a bf(C++) variant (ti(bison++)) creating a parser class. Although the tt(bison++) program produces code that can be used in bf(C++) programs it also shows many characteristics that are more suggestive of a bf(C) context than a bf(C++) context. In January 2005 I rewrote parts of Alain's tt(bison++) program, resulting in the original version of the program hi(bisonc++) bf(bisonc++). Then, in May 2005 a complete rewrite of the tt(bisonc++) parser generator was completed (version number 0.98). Current versions of tt(bisonc++) can be downloaded from tlurl(https://fbb-git.gitlab.io/bisoncpp/). Binary versions for various architectures are available as, e.g., url(Debian)(http://www.debian.org) package (including tt(bisonc++)'s documentation). tt(Bisonc++) creates a cleaner parser class than tt(bison++). In particular, it derives the parser class from a base-class, containing the parser's token- and type-definitions as well as all member functions which should not be (re)defined by the programmer. As a result of this approach, the generated parser class is very small, declaring only members that are actually defined by the programmer (as well as some other members, generated by tt(bisonc++) itself, implementing the parser's ti(parse()) member). One member that is em(not) implemented by default is tt(lex), producing the next lexical token. When the directive tt(%scanner) (see section ref(BISONDEF)) is used, tt(bisonc++) produces a standard implementation for this member; otherwise it must be implemented by the programmer. In early 2012 the program hi(flexc++) bf(flexc++) tlurl(http://flexcpp.org/) reached its initial release. Like tt(bisonc++) it is part of the url(Debian linux distribution)(http://www.debian.org). Jean-Paul van Oosten (email(jp@jpvanoosten.nl)) and Richard Berendsen (email(richardberendsen@xs4all.nl)) started the tt(flexc++) project in 2008 and the final program was completed by Jean-Paul and me between 2010 and 2012. These sections of the annotations() focus on tt(bisonc++) as our emi(parser generator) and tt(flexc++) as our lexical scanner generator. Previous releases of the annotations() were using tt(flex) as the scanner generator. Using tt(flexc++) and tt(bisonc++) tt(class)-based scanners and parsers are generated. The advantage of this approach is that the interface to the scanner and the parser tends to become cleaner than without using tt(class) interfaces. Furthermore, classes allow us to get rid of most if not all global variables, making it easy to use multiple parsers in one program. Below two example programs are developed. The first example only uses tt(flexc++). The generated scanner monitors the production of a file from several parts. That example focuses on the lexical scanner and on switching files while churning through the information. The second example uses both tt(flexc++) and tt(bisonc++) to generate a scanner and a parser transforming standard arithmetic expressions to their postfix notations, commonly used in code generated by compilers and in tt(HP)-calculators. In the second example the emphasis is mainly on tt(bisonc++) and on composing a scanner object inside a generated parser. c++-annotations-12.5.0/yo/concrete/parentslurp.yo0000644000175000017500000000570414466730207020666 0ustar frankfrank The class ti(ParentSlurp), derived from tt(Fork), starts a child process executing a stand-alone program (like tt(/bin/ls)). The (standard) output of the executed program is not shown on the screen but is read by the parent process. For demonstration purposes the parent process writes the lines it receives to its standard output stream, prepending linenumbers to the lines. It is attractive to redirect the parent's standard em(input) stream to allow the parent to read the em(output) from the child process using its tt(std::cin) em(input) stream. Therefore, the only pipe in the program is used as an em(input) pipe for the parent, and an em(output) pipe for the child. The class tt(ParentSlurp) has the following characteristics: itemization( it() It is derived from tt(Fork). Before starting tt(ParentSlurp)'s class interface, the compiler must have read tt(fork.h) and tt(pipe.h). The class only uses one data member, a tt(Pipe) object tt(d_pipe). it() As tt(Pipe)'s constructor already defines a pipe, and as tt(d_pipe) is automatically initialized by tt(ParentSlurp)'s default constructor, which is implicitly provided, all additional members only exist for tt(ParentSlurp)'s own benefit so they can be defined in the class's (implicit) tt(private) section. Here is the class's interface: verbinclude(//CLASS examples/parentslurp.h) it() The tt(childRedirections) member configures the writing end of the pipe. So, all information written to the child's standard output stream ends up in the pipe. The big advantage of this is that no additional streams are needed to write to a file descriptor: verbinclude(//CHILDREDIR examples/parentslurp.h) it() The tt(parentRedirections) member, configures the reading end of the pipe. It does so by connecting the reading end of the pipe to the parent's standard input file descriptor (tt(STDIN_FILENO)). This allows the parent to perform extractions from tt(cin), not requiring any additional streams for reading. verbinclude(//PARENTREDIR examples/parentslurp.h) it() The tt(childProcess) member only needs to concentrate on its own actions. As it only needs to execute a program (writing information to its standard output), the member can consist of one single statement: verbinclude(//CHILDPROC examples/parentslurp.h) it() The tt(parentProcess) member simply `slurps' the information appearing at its standard input. Doing so, it actually reads the child's output. It copies the received lines to its standard output stream prefixing line numbers to them: verbinclude(//PARENT examples/parentslurp.cc) ) The following program simply constructs a tt(ParentSlurp) object, and calls its tt(fork()) member. Its output consists of a numbered list of files in the directory where the program is started. Note that the program also needs the tt(fork.o, pipe.o) and tt(waitforchild.o) object files (see earlier sources): verbinclude(//MAIN examples/parentslurp.cc) c++-annotations-12.5.0/yo/concrete/basicfork.yo0000644000175000017500000001161314466730207020246 0ustar frankfrank A basic tt(Fork) class should hide all bookkeeping details of a system call like tt(fork) from its users. The class tt(Fork) developed here does just that. The class itself only ensures the proper execution of the tt(fork) system call. Normally, tt(fork) is called to start a child process, usually boiling down to the execution of a separate process. This child process may expect input at its standard input stream and/or may generate output to its standard output and/or standard error streams. tt(Fork) does not know all this, and does not have to know what the child process will do. tt(Fork) objects should be able to start their child processes. tt(Fork)'s constructor cannot know what actions its child process should perform. Similarly, it cannot know what actions the parent process should perform. For these kind of situations, the emi(template method design pattern) hi(design pattern: template method) was developed. According to Gamma c.s., the em(template method design pattern) quote( ``Define(s) the skeleton of an algorithm in an operation, deferring some steps to subclasses. [The] Template Method (design pattern) lets subclasses redefine certain steps of an algorithm, without changing the algorithm's structure.'' ) This design pattern allows us to define an emi(abstract base class) hi(base class) already providing the essential steps related to the tt(fork) system call, deferring the implementation of other parts of the tt(fork) system call to subclasses. The tt(Fork) abstract base class has the following characteristics: itemization( it() It defines a data member tt(d_pid). In the parent process this data member contains the child's emi(process id) and in the child process it has the value 0. Its public interface declares only two members: itemization( it() a ti(fork) member function, responsible for the actual forking (i.e., it creates the (new) child process); it() a tt(virtual) destructor tt(~Fork) (having an empty body). ) Here is tt(Fork)'s interface: verbinclude(//CLASS examples/fork.h) it() All other non-virtual member functions are declared in the class's tt(protected) section and can thus em(only) be used by derived classes. They are: itemization( itt(pid()): The member function tt(pid) allows derived classes to access the system tt(fork)'s return value: verbinclude(//PID examples/fork.h) itt(waitForChild()): The member tt(int waitForChild) can be called by parent processes to wait for the completion of their child processes (as discussed below). This member is declared in the class interface. Its implementation is: verbinclude(-a examples/waitforchild.cc) This simple implementation returns the child's emi(exit status) to the parent. The called system function ti(waitpid) em(blocks) until the child terminates. ) it() When tt(fork) system calls are used, em(parent processes) hi(parent process) and em(child processes) hi(child process) must always be distinguished. The main distinction between these processes is that tt(d_pid) becomes the child's process-id in the parent process, while tt(d_pid) becomes 0 in the child process itself. Since these two processes must always be distinguished (and present), their implementation by classes derived from tt(Fork) is enforced by tt(Fork)'s interface: the members tt(childProcess), defining the child process' actions and tt(parentProcess), defining the parent process' actions were defined as pure virtual functions. it() communication between parent- and child processes may use standard streams or other facilities, like em(pipes) (cf. section ref(PIPE)). To facilitate this inter-process communication, derived classes em(may) implement: itemization( itt(childRedirections()): this member should be overridden by derived classes if any standard stream (tt(cin, cout,)) or tt(cerr) must be redirected in the em(child) process (cf. section ref(REDIRECTION)). By default it has an empty implementation; itt(parentRedirections()): this member should be overridden by derived classes if any standard stream (tt(cin, cout,)) or tt(cerr) must be redirected in the em(parent) process. By default it has an empty implementation. ) Redirection of the standard streams is necessary if parent and child processes must communicate with each other via the standard streams. Here are their default definitions. Since these functions are virtual functions they should not be implemented inline, but in their own source file: verbinclude(//REDIRECT examples/forkvirtual.cc) ) c++-annotations-12.5.0/yo/concrete/monitor.yo0000644000175000017500000000232214466730207017767 0ustar frankfrank The tt(monitor) program uses a tt(Monitor) object doing most of the work. The class tt(Monitor)'s public interface only offers a default constructor and one member, tt(run), to perform its tasks. All other member functions are located in the class's tt(private) section. tt(Monitor) defines the tt(private) enum tt(Commands), symbolically listing the various commands its input language supports, as well as several data members. Among the data members are a tt(Selector) object and a tt(map) using child order numbers as its keys and pointer to tt(Child) objects (see section ref(CHILD)) as its values. Furthermore, tt(Monitor) has a static array member tt(s_handler[]), storing pointers to member functions handling user commands. A destructor should be implemented as well, but its implementation is left as an exercise to the reader. Here is tt(Monitor)'s interface, including the interface of the nested class tt(Find) that is used to create a function object: verbinclude(//CLASS examples/monitor/monitor.h) Since there's only one non-class type data member, the class's constructor is a very simple function which could be implemented inline: verbinclude(//CONS examples/monitor/monitor.h) c++-annotations-12.5.0/yo/concrete/polygram.yo0000644000175000017500000000265414466730207020142 0ustar frankfrankNow that the tt(Semantic) class template has been developed it's time to put it to use in the tt(Parser) class. The parser's semantic value is tt(spSemBase). The parser's base class must be informed about this type, for which the tt(%baseclass-preinclude) directive is used. All other directives are standard and do not require further explanations: verbinclude(//HEAD poly2/parser/grammar) The grammar's rules simply consist of a series of tt(rule) nonterminals: verbinclude(//RULES poly2/parser/grammar) tt(Int) values are stored in tt(Semantic) objects, text is stored in tt(Semantic) values: verbinclude(//INT poly2/parser/grammar) Comma separated lists of arguments are processed as follows: the first argument is stored in a tt(Semantic); additional values are added to the vector using tt(vector::push_back). Note that we've defined the vector as mutable: addition of values to the vector is OK, but the values themselves remain as-is, and so the vector stores shared pointers to tt(SemBase const) values: verbinclude(//ARGS poly2/parser/grammar) The definition of the tt(rule) production rule completes our little grammar: an alternative suggesting an assignment echoes the received names and values, and an alternative suggesting a function call uses a support member tt(display) to display the received name and arguments: verbinclude(//RULE poly2/parser/grammar) c++-annotations-12.5.0/yo/concrete/binop.yo0000644000175000017500000000266614466730207017422 0ustar frankfrankAs we've seen in section ref(OVERLOADBINARY) binary operators expecting tt(const &) arguments can be implemented using a member implementing the operation, only offering the basic exception guarantee. This latter function can in turn be implemented using the binary assignment member. The following examples illustrated this approach for a fictitious class tt(Binary): verbinclude(-a ../overloading/examples/binary4.h) Eventually, the implementation of binary operators depends on the availability of the member implementing the basic binary operation, modifying the object calling that member (i.e., tt(void Binary::add(Binary const &)) in the example). Since template functions are not instantiated before they are actually used we can call non-existing functions from template functions that are never instantiated. If such a template function is never instantiated, nothing happens; if it is (accidentally) instantiated, then the compiler generates an error message, complaining about the missing function. This allows us to implement all binary operators, movable and non-movable, as templates. In the following subsections we develop the class template tt(Binops), prividing binary operators. A complete implementation of a class tt(Derived) illustrating how addition and insertion operators can be added to a class is provided in the file tt(annotations/yo/concrete/examples/binopclasses.cc) in the annotations()' source archive. c++-annotations-12.5.0/yo/concrete/fistreamexample.yo0000644000175000017500000000641014466730207021470 0ustar frankfrank There is only one additional public member: tt(setField(field const &)). This member defines the size of the next field to extract. Its parameter is a reference to a tt(field) class, a em(manipulator class) defining the width of the next field. Since a tt(field &) is mentioned in tt(Fistream)'s interface, tt(field) must be declared before tt(Fistream)'s interface starts. The class tt(field) itself is simple and declares tt(Fistream) as its friend. It has two data members: tt(d_width) specifies the width of the next field, and tt(d_newWidth) which is set to tt(true) if tt(d_width)'s value should actually be used. If tt(d_newWidth) is false, tt(Fistream) returns to its standard extraction mode. The class tt(field) has two constructors: a default constructor, setting tt(d_newWidth) to tt(false), and a second constructor expecting the width of the next field to extract as its value. Here is the class tt(field): verbinclude(//FIELD examples/fistream/fistream.h) Since tt(field) declares tt(Fistream) as its friend, tt(setField) may inspect tt(field)'s members directly. Time to return to tt(setField). This function expects a reference to a tt(field) object, initialized in one of three different ways: itemization( itt(field()): When tt(setField)'s argument is a tt(field) object constructed by its default constructor the next extraction will use the same field width as the previous extraction. itt(field(0)): When this tt(field) object is used as tt(setField)'s argument, fixed-sized field extraction stops, and the tt(Fistream) acts like any standard tt(istream) object again. itt(field(x)): When the tt(field) object itself is initialized by a non-zero size_t value tt(x), then the next field width is tt(x) characters wide. The preparation of such a field is left to tt(setBuffer), tt(Fistream)'s only private member. ) Here is tt(setField)'s implementation: verbinclude(//SETFIELD examples/fistream/fistream.cc) The private member tt(setBuffer) defines a buffer of tt(d_width + 1) characters and uses tt(read) to fill the buffer with tt(d_width) characters. The buffer is an NTBS. This buffer is used to initialize the tt(d_iss) member. tt(Fistream)'s tt(rdbuf) member is used to extract the tt(d_str)'s data via the tt(Fistream) object itself: verbinclude(//SETBUFFER examples/fistream/fistream.cc) Although tt(setField) could be used to configure tt(Fistream) to use or not to use fixed-sized field extraction, using manipulators is probably preferable. To allow tt(field) objects to be used as manipulators an overloaded extraction operator was defined. This extraction operator accepts tt(istream &) and a tt(field const &) objects. Using this extraction operator, statements like verb(fis >> field(2) >> x >> field(0);) are possible (assuming tt(fis) is a tt(Fistream) object). Here is the overloaded oprshift(), as well as its declaration: verbinclude(//OPEX examples/fistream/fistream.cc) Declaration: verbinclude(//OPEX examples/fistream/fistream.h) Finally, an example. The following program uses a tt(Fistream) object to url-decode url-encoded information appearing at its standard input: verbinclude(//MAIN examples/fistream/main.cc) c++-annotations-12.5.0/yo/concrete/definition.yo0000644000175000017500000001631614466730207020440 0ustar frankfrank The i(declaration section) contains several sets of declarations, among which definitions of all the tokens used in the grammar and the priorities and associativities of the mathematical operators. Moreover, several new and important specifications can be used here as well. Those relevant to our current example and only available in tt(bisonc++) are discussed here. The reader is referred to tt(bisonc++)'s man-page for a full description. itemization( it() bi(%baseclass-preinclude) tt(header)nl() Use tt(header) as the pathname to the file pre-included in the parser's base-class header. This declaration is useful in situations where the base class header file refers to types which might not yet be known. E.g., with ti(%union) a tt(std::string *) field might be used. Since the class tt(std::string) might not yet be known to the compiler once it processes the base class header file we need a way to inform the compiler about these classes and types. The suggested procedure is to use a pre-include header file declaring the required types. By default tt(header) is surrounded by double quotes (using, e.g., tt(#include "header")). When the argument is surrounded by angle brackets tt(#include
) is included. In the latter case, quotes might be required to escape interpretation by the shell (e.g., using tt(-H '
')). it() bi(%filenames) tt(header) nl() Defines the generic name of all generated files, unless overridden by specific names. By default the generated files use the class-name as the generic file name. it() bi(%scanner) tt(header)nl() Use tt(header) as the pathname to the file pre-included in the parser's class header. This file should define a class tt(Scanner), offering a member tt(int lex()) producing the next token from the input stream to be analyzed by the parser generated by tt(bisonc++). When this option is used the parser's member tt(int lex()) is predefined as (assuming the default parser class name tt(Parser) is used): verb(inline int Parser::lex() { return d_scanner.lex(); }) and an object tt(Scanner d_scanner) is composed into the parser. The tt(d_scanner) object is constructed by its default constructor. If another constructor is required, the parser class may be provided with an appropriate (overloaded) parser constructor after having constructed the default parser class header file using tt(bisonc++). By default tt(header) is surrounded by double quotes (using, e.g., tt(#include "header")). When the argument is surrounded by angle brackets tt(#include
) is included. it() bi(%stype) tt(typename) nl() The type of the semantic value of tokens. The specification tt(typename) should be the name of an unstructured type (e.g., tt(size_t)). By default it is tt(int). See tt(YYSTYPE) in tt(bison). It should not be used if a tt(%union) specification is used. Within the parser class, this type may be used as tt(STYPE). it() bi(%union) tt(union-definition) nl() Acts identically to the tt(bison) declaration. As with tt(bison) this generates a union for the parser's semantic type. The union type is named tt(STYPE). If no tt(%union) is declared, a simple stack-type may be defined using the tt(%stype) declaration. If no tt(%stype) declaration is used, the default stacktype (tt(int)) is used. ) An example of a tt(%union) declaration is: verb( %union { int i; double d; };) In pre-C++11 code a i(union) cannot contain objects as its fields, as constructors cannot be called when a union is created. This means that hi(string: as union member) a tt(string) cannot be a member of the union. A tt(string *), however, em(is) a possible union member. It might also be possible to use em(unrestricted unions) (cf. section ref(UNIONS)), having class type objects as fields. As an aside: the scanner does not have to know about such a union. It can simply pass its scanned text to the parser through its ti(matched) member function. For example using a statement like verb( $$.i = A2x(d_scanner.matched());) matched text is converted to a value of an appropriate type. Tokens and non-terminals can be associated with union fields. This is strongly advised, as it prevents type mismatches, since the compiler may then check for type correctness. At the same time, the bison specific variables tt($$), tt($1), tt($2), etc. may be used, rather than the full field specification (like tt($$.i)). A non-terminal or a token may be associated with a union field using the tt() specification. E.g., verb( %token INT // token association (deprecated, see below) DOUBLE %type intExpr // non-terminal association) In the example developed here, both the tokens and the non-terminals can be associated with a union field. However, as noted before, the scanner does not have to know about all this. In our opinion, it is cleaner to let the scanner do just one thing: scan texts. The em(parser), knowing what the input is all about, may then convert strings like tt("123") to an integer value. Consequently, the association of a union field and a token is discouraged. Below, while describing the grammar's rules, this is further illustrated. In the tt(%union) discussion the ti(%token) and ti(%type) specifications should be noted. They are used to specify the tokens (terminal symbols) that can be returned by the scanner, and to specify the return types of non-terminals. Apart from tt(%token) the token declarators ti(%left), ti(%right), and ti(%nonassoc) can be used to specify the associativity of operators. The tokens mentioned at these indicators are interpreted as tokens indicating operators, associating in the indicated direction. The precedence of operators is defined by their order: the first specification has the lowest priority. To overrule a certain precedence in a certain context ti(%prec) can be used. As all this is standard tt(bisonc++) practice, it isn't further elaborated here. The documentation provided with tt(bisonc++)'s distribution should be consulted for further reference. Here is the specification of the calculator's declaration section: verbinclude(//DECLARATION bisonc++/parser/grammar) In the declaration section tt(%type) specifiers are used, associating the tt(intExpr) rule's value (see the next section) to the tt(i)-field of the semantic-value union, and associating tt(doubleExpr)'s value to the tt(d)-field. This approach, admittedly, is rather complex, as expression rules must be included for each of the supported union types. Alternatives are definitely possible, and involve the use of em(polymorphic semantic values), covered in detail in the url(Bisonc++ user guide) (http://fbb-git.gitlab.io/bisoncpp/manual/bisonc++.html). c++-annotations-12.5.0/yo/concrete/bison.yo0000644000175000017500000000567314466730207017426 0ustar frankfrankThe i(grammar specification file) required by ti(bisonc++) is comparable to the specification file required by ti(bison). Differences are related to the class nature of the resulting parser. Our calculator distinguishes real numbers from integers, and supports a basic set of arithmetic operators. tt(Bisonc++) should be used as follows: itemization( it() As usual, a grammar is defined. With tt(bisonc++) this is no different, and tt(bisonc++) grammar definitions are for all practical purposes identical to tt(bison)'s grammar definitions. it() Having specified the grammar and (usually) some declarations tt(bisonc++) can generate files defining the parser class and the implementation of the member function tt(parse). it() All class members (except those that are required for the proper functioning of the member tt(parse)) must be separately implemented. Of course, they should also be declared in the parser class's header. At the very least the member ti(lex) must be implemented. This member is called by tt(parse) to obtain the next available token. However, tt(bisonc++) offers a facility providing a standard implementation of the function tt(lex). The member function hi(error)tt(error(char const *msg)) is given a simple default implementation that may be modified by the programmer. The member function tt(error) is called when tt(parse) detects (syntactic) errors. it() The parser can now be used in a program. A very simple example would be: verb(int main() { Parser parser; return parser.parse(); }) ) The tt(bisonc++) hi(bisonc++: grammar file) specification file has two sections: itemization( it() The em(declaration section). In this section bison's tokens, and the priority rules for the operators are declared. However, tt(bisonc++) also supports several new declarations. These new declarations are important and are discussed below. it() The em(rules section). The i(grammatical rules) define the grammar. This section is identical to the one required by tt(bison), albeit that some members that were available in tt(bison) and tt(bison++) are obsolete in tt(bisonc++), while other members can be used in a wider context. For example, bf(ACCEPT) and bf(ABORT) can be called from any member called from the parser's action blocks to terminate the parsing process. ) Readers familiar with tt(bison) may note that there is no emi(header section) anymore. Header sections are used by bison to provide for the necessary declarations allowing the compiler to compile the bf(C) function generated by tt(bison). In bf(C++) declarations are part of or already used by class definitions. Therefore, a parser generator generating a bf(C++) class and some of its member functions does not require a header section anymore. c++-annotations-12.5.0/yo/concrete/run.yo0000644000175000017500000000544314466730207017113 0ustar frankfrank tt(Monitor)'s core activities are performed by tt(run). It performs the following tasks: itemization( it() Initially, the tt(Monitor) object only monitors its standard input. The set of input file descriptors to which tt(d_selector) listens is initialized to tt(STDIN_FILENO). it() Then, in a loop tt(d_selector)'s tt(wait) function is called. If input on tt(cin) is available, it is processed by tt(processInput). Otherwise, the input has arrived from a child process. Information sent by children is processed by tt(processChild). it() To prevent emi(zombie)em(s), the child processes must catch em(their) children's termination signals. This is discussed below. As noted by Ben Simons (tt(ben at mrxfx dot com)) tt(Monitor) must not catch the termination signals. Instead, the process spawning child processes has that responsibility (the underlying principle being that a parent process is responsible for its child processes; a child process, in turn, is responsible for its own child processes). it() As stated, tt(run)'s source file also defines and initializes tt(s_initialize) to ensure the proper initialization of the tt(s_handler) array. ) Here is tt(run)'s implementation and tt(s_initialize)'s definition: verbinclude(-a examples/monitor/run.cc) The member function tt(processInput) reads the commands entered by the user using the program's standard input stream. The member itself is rather simple. It calls tt(next) to obtain the next command entered by the user, and then calls the corresponding function using the matching element of the tt(s_handler[]) array. Here are the members tt(processInput) and tt(next): verbinclude(//INPUT examples/monitor/processinput.cc) verbinclude(//NEXT examples/monitor/processinput.cc) All other input sensed by tt(d_select) is created by child processes. Because tt(d_select)'s tt(readFd) member returns the corresponding input file descriptor, this descriptor can be passed to tt(processChild). Using a ti(IFdStreambuf) (see section ref(IFDBUF)), its information is read from an input stream. The communication protocol used here is rather basic. For every line of input sent to a child, the child replies by sending back exactly one line of text. This line is then read by tt(processChild): verbinclude(//CHILD examples/monitor/processchild.cc) The construction tt(d_child[fd]->pid()) used in the above source deserves some special attention. tt(Monitor) defines the data member tt(map> d_child). This map contains the child's order number as its key, and a (shared) pointer to the tt(Child) object as its value. A shared pointer is used here, rather than a tt(Child) object, since we want to use the facilities offered by the map, but don't want to copy a tt(Child) object time and again. c++-annotations-12.5.0/yo/concrete/lexer.yo0000644000175000017500000000234614466730207017425 0ustar frankfrank The function matching the i(regular expression) rules (tt(lex)) is a member of the class hi(scanner)tt(Scanner). Since tt(Scanner) is derived from tt(ScannerBase), it has access to all of tt(ScannerBase)'s protected members that execute the lexical scanner's regular expression matching algorithm. Looking at the regular expressions themselves, notice that we need rules to recognize comment, ti(#include) directives, and all remaining characters. This all is fairly standard practice. When an tt(#include) directive is sensed, the directive is parsed by the scanner. This too is common practice. Our lexical scanner performs the following tasks: itemization( it() As usual, i(preprocessor directive)s are not analyzed by a parser, but by the lexical scanner; it() The scanner uses a i(mini scanner) to extract the filename from the directive, throwing a exception if this fails; it() If the filename could be extracted, processing switches to the next stream, controlling for a maximum nesting depth. it() Once the end of the current file has been reached processing automatically returns to the previous file, restoring the previous file name and line number. The scanner returns 0 if all files have been processed. ) c++-annotations-12.5.0/yo/concrete/fork.yo0000644000175000017500000000276314466730207017252 0ustar frankfrankFrom the bf(C) programming language the ti(fork) system call is well known. When a program needs to start a new process, ti(system) can be used. The function tt(system) requires the program to wait for the emi(child process) to terminate. The more general way to spawn subprocesses is to use tt(fork). In this section we investigate how bf(C++) can be used to wrap classes around a complex system call like tt(fork). Much of what follows in this section directly applies to the Unix operating system, and the discussion therefore focuses on that operating system. Other systems usually provide comparable facilities. What follows is closely related to the em(Template Design Pattern)hi(design pattern) (cf. em(Gamma et al.) (1995) hi(Gamma, E.) i(Design Patterns), Addison-Wesley) When tt(fork) is called, the current program is duplicated in memory, thus creating a new process. Following this duplication both processes continue their execution just below the tt(fork) system call. The two processes may inspect tt(fork)'s return value: the return value in the original process (called the emi(parent process)) differs from the return value in the newly created process (called the emi(child process)): itemization( it() In the em(parent process) tt(fork) returns the emi(process ID) of the (child) process that was created by the tt(fork) system call. This is a positive integer value. it() In the em(child process) tt(fork) returns 0. it() If tt(fork) fails, -1 is returned. ) c++-annotations-12.5.0/yo/concrete/promotions.yo0000644000175000017500000001163314466730207020516 0ustar frankfrankThe function templates introduced in the previous section do not support promotions. E.g., a statement like verb( result = rhs + 2;) generates a compilation error as promotions are not recognized by the template argument deduction algorithm. Currently, the above statement needs to be rewritten to have it accepted by the compiler: verb( result = rhs + Class{ 2 };) If promotions are welcome, how can we change the arithmetic operator function templates so that promotions are performed? With promotions the arguments of the operator functions may be of any type, at least one of them must be of the class type offering the matching compound assignment operator. But when designing the function template we can't say which of the two operands has that class type. So we have to specify two template types parameters for the two parameters of the operator functions. The function template must therefore start with something like this: verb( template ReturnType operator+(LHS const &lhs, RHS const &rhs)) At this point we can't yet specify tt(ReturnType). It is tt(LHS) if tt(RHS) can be promoted to or is equal to tt(LHS), it is be tt(RHS) if tt(LHS) is promoted to tt(RHS). To determine whether tt(RHS) can be promoted to tt(LHS) we now design a simple template meta programming class tt(LpromotesR) using two template type parameters, defining the value tt(true) (1) if the second (right hand) type can be promoted to the first (left-hand) type, and defining the value tt(false) (0) if not. Here we use the same principle seen before in section ref(TYPECONV), link(type convertibility)(TYPECONV): verb( template class LpromotesR { struct Char2 { char array[2]; }; static R const &makeR(); static char test(L const &); static Char2 test(...); public: LpromotesR() = delete; enum { yes = sizeof(test(makeR())) == sizeof(char) }; };) In tt(class LpromotesR) the function tt(test(L const &)) is selected if tt(R) can be promoted to tt(L), and tt(test(...)) is selected if not. The different sizes of the return types of these two tt(test) functions allows the compiler to assign 1 or 0 to the class's tt(enum) value tt(yes). The value tt(yes) (correctly) is 0 for tt(R) types mentioned in constructors declared with the tt(explicit) keyword, and it (correctly) is 1 if tt(L) and tt(R) happen to be the same types. Now that we can determine whether a type can be promoted to another type, it is possible to select either tt(LHS) or tt(RHS) as the function template's return type. If tt(RHS) can be promoted to tt(LHS) use tt(LHS) as the function template's return type, otherwise use RHS. Of course there is a third possibility: the tt(LHS) and tt(RHS) types cannot be used by each other's constructors. In that case, unless there is another constructor lying around somewhere handling that situation, the compiler generates an error like: verb( no match for 'operator+' in '...') Back to promotable types. We are now able to determine which type can be promoted, using tt(LpromotesR). This yields a value that can be used as selector in the tt(IfElse) template meta programming class template, introduced earlier (cf. section ref(IFELSE)). Now that we can select either tt(LHS) or tt(RHS) as the operator template function's return type, we're able to construct our arithmetic operator function template supporting promotions: verb( template typename FBB::IfElse::yes, LHS, RHS>::type operator<<(LHS const &lhs, RHS const &rhs) { using Type = typename FBB::IfElse< FBB::LpromotesR< LHS, RHS >::yes, LHS, RHS >::type; Type tmp(lhs); return std::move(tmp) << type(rhs); }) The function's return type is tt(IfElse)'s tt(type), selected as either tt(LHS) (if tt(RHS) can be promoted to tt(LHS)) or tt(RHS). The same trick is used in the function's body to determine tt(tmp)'s type. Now promotions are possible. The function template defining an rvalue reference parameter remains as-is. Together they allow the compiler to make the following decisions (using tt(Class) as the intended class name, tt(Type) as a type that is promotable to tt(Class), and tt(@) as the generic indication of the used operator). Unless otherwise specified the function template defining the parameter list tt((LHS const &lhs, RHS const &rhs)) is used: verb( Class obj; Type value; obj @ obj // no promotions obj @ Class() // same obj @ value; // value is promoted to Class Class() @ value; // same value @ obj; // same value @ Class(); // same Class() @ obj; // calls operator@(Class &&, Class const &) Class() @ Class(); // same) c++-annotations-12.5.0/yo/concrete/intro.yo0000644000175000017500000000167514466730207017445 0ustar frankfrankIn this chapter concrete examples of bf(C++) programs, classes and templates are presented. Topics covered by the annotations() such as virtual functions, tt(static) members, etc. are illustrated in this chapter. The examples roughly follow the organization of earlier chapters. As an additional topic, not just providing examples of bf(C++) the subjects of i(scanner) and i(parser) generators are covered. We show how these tools may be used in bf(C++) programs. These additional examples assume a certain familiarity with the concepts underlying these tools, like grammars, parse-trees and hi(grammar) hi(parse-tree) parse-tree decoration. Once the input for a program exceeds a certain level of complexity, it's attractive to use scanner- and parser-generators to create the code doing the actual input processing. One of the link(examples)(BisonAndFlex) in this chapter describes the usage of these tools in a bf(C++) environment. c++-annotations-12.5.0/yo/concrete/child.yo0000644000175000017500000001011314466730207017360 0ustar frankfrank When the tt(Monitor) object starts a child process, it creates an object of the class tt(Child). The tt(Child) class is derived from the class tt(Fork), allowing it to operate as a emi(daemon) (as discussed in the previous section). Since tt(Child) is a daemon class, we know that its parent process must be defined as an empty function. Its tt(childProcess) member has a non-empty implementation. Here are the characteristics of the class tt(Child): itemization( it() The tt(Child) class has two tt(Pipe) data members, to handle communications between its own child- and parent processes. As these pipes are used by the tt(Child)'s child process, their names refer to the child process. The child process reads from tt(d_in), and writes to tt(d_out). Here is the interface of the class tt(Child): verbinclude(//CLASS examples/monitor/child.h) it() The tt(Child)'s constructor simply stores its argument, a child-process order number, in its own tt(d_nr) data member: verbinclude(//CONS examples/monitor/child.h) it() The tt(Child)'s child process obtains commands from its standard input stream and writes its output to its standard output stream. Since the actual communication channels are pipes, redirections must be used. The tt(childRedirections) member looks like this: verbinclude(//CHILD examples/monitor/child.cc) it() Although the parent process performs no actions, it must configure some redirections. Realizing that the names of the pipes indicate their functions in the child process. So the parent em(writes) to tt(d_in) and em(reads) from tt(d_out). Here is tt(parentRedirections): verbinclude(//PARENT examples/monitor/child.cc) it() The tt(Child) object exists until it is destroyed by the tt(Monitor)'s tt(stopChild) member. By allowing its creator, the tt(Monitor) object, to access the parent-side ends of the pipes, the tt(Monitor) object can communicate with the tt(Child)'s child process via those pipe-ends. The members tt(readFd) and tt(writeFd) allow the tt(Monitor) object to access these pipe-ends: verbinclude(//PIPES examples/monitor/child.h) it() The tt(Child) object's child process performs two tasks: itemization( it() It must reply to information appearing at its standard input stream; it() If no information has appeared within a certain time frame (the implementations uses an interval of five seconds), then a message is written to its standard output stream. ) To implement this behavior, tt(childProcess) defines a local tt(Selector) object, adding tt(STDIN_FILENO) to its set of monitored input file descriptors. Then, in an endless loop, tt(childProcess) waits for tt(selector.wait()) to return. When the alarm goes off it sends a message to its standard output (hence, into the writing pipe). Otherwise, it echoes the messages appearing at its standard input to its standard output. Here is the tt(childProcess) member: verbinclude(//PROCESS examples/monitor/child.cc) it() Two accessors are defined allowing the tt(Monitor) object to obtain the tt(Child)'s process ID and its order number: verbinclude(//PIDNR examples/monitor/child.h) it() A tt(Child) process terminates when the user enters a tt(stop) command. When an existing child process number was entered, the corresponding tt(Child) object is removed from tt(Monitor)'s tt(d_child) map. As a result, its destructor is called. tt(Child)'s destructor calls tt(kill) to terminate its child, and then waits for the child to terminate. Once its child has terminated, the destructor has completed its work and returns, thus completing the erasure from tt(d_child). The current implementation fails if the child process doesn't react to the tt(SIGTERM) signal. In this demonstration program this does not happen. In `real life' more elaborate killing-procedures may be required (e.g., using tt(SIGKILL) in addition to tt(SIGTERM)). As discussed in section ref(CONSEXCEPTIONS) it em(is) important to ensure the proper destruction. Here is the tt(Child)'s destructor: verbinclude(//CHILDDES examples/monitor/child.cc) ) c++-annotations-12.5.0/yo/concrete/lexer/0000755000175000017500000000000014624637124017047 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/lexer/build0000755000175000017500000000075214466730207020100 0ustar frankfrank#!/bin/bash case "$1" in ("") echo " usage: 'build prog' to build the program, 'build clean' to cleanup " exit 1 ;; (prog) cd scanner flexc++ lexer || exit 1 cd .. g++ --std=c++11 -Wall -olexer lexer.cc scanner/*.cc || exit 1 echo " ready; run the program as 'lexer in.1' " ;; (clean) cd scanner rm -f ../lexer lex.cc scannerbase.h echo " done " ;; esac exit 1 c++-annotations-12.5.0/yo/concrete/lexer/in.10000644000175000017500000000005514466730207017537 0ustar frankfrankbefore #include #include after c++-annotations-12.5.0/yo/concrete/lexer/lexer.cc0000664000175000017500000000051514624637131020476 0ustar frankfrank#include "lexer.ih" int main(int argc, char **argv) try { if (argc == 1) { cerr << "Filename argument required\n"; return 1; } Scanner scanner(argv[1], "-"); scanner.setDebug(argc > 2); return scanner.lex(); } catch (exception const &exc) { cerr << exc.what() << '\n'; return 1; } c++-annotations-12.5.0/yo/concrete/lexer/scanner/0000755000175000017500000000000014624637124020500 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/lexer/scanner/scanner.ih0000664000175000017500000000005314624637127022456 0ustar frankfrank#include "scanner.h" using namespace std; c++-annotations-12.5.0/yo/concrete/lexer/scanner/scanner.h0000664000175000017500000000243514624637127022313 0ustar frankfrank// Generated by Flexc++ V0.94.00 on Thu, 23 Feb 2012 16:23:09 +0100 #ifndef Scanner_H_INCLUDED_ #define Scanner_H_INCLUDED_ // $insert baseclass_h #include "scannerbase.h" // $insert classHead class Scanner: public ScannerBase { std::string d_nextSource; public: explicit Scanner(std::istream &in = std::cin, std::ostream &out = std::cout); Scanner(std::string const &infile, std::string const &outfile); // $insert lexFunctionDecl int lex(); private: int lex__(); int executeAction__(size_t ruleNr); void print(); void preCode(); // re-implement this function for code that must // be exec'ed before the patternmatching starts void switchSource(); }; // $insert scannerConstructors inline Scanner::Scanner(std::istream &in, std::ostream &out) : ScannerBase(in, out) {} inline Scanner::Scanner(std::string const &infile, std::string const &outfile) : ScannerBase(infile, outfile) {} // $insert inlineLexFunction inline int Scanner::lex() { return lex__(); } inline void Scanner::preCode() { // optionally replace by your own code } inline void Scanner::print() { print__(); } #endif // Scanner_H_INCLUDED_ c++-annotations-12.5.0/yo/concrete/lexer/scanner/lexer0000644000175000017500000000136614466730207021550 0ustar frankfrank//SYMBOLS %filenames scanner %debug %max-depth 3 %x comment %x include //= //RULES %% // The comment-rules: comment is ignored. "//".* // ignore eoln comment "/*" begin(StartCondition__::comment); { .|\n // ignore all characters in std C comment "*/" begin(StartCondition__::INITIAL); } // File switching: #include #include[ \t]+"<" begin(StartCondition__::include); { [^ \t>]+ d_nextSource = matched(); ">"[ \t]*\n switchSource(); .|\n throw runtime_error("Invalid include statement"); } // The default rule: echo anything else to std::cout .|\n echo(); //= c++-annotations-12.5.0/yo/concrete/lexer/scanner/switchsource.cc0000664000175000017500000000017414624637131023533 0ustar frankfrank#include "scanner.ih" void Scanner::switchSource() { pushStream(d_nextSource); begin(StartCondition__::INITIAL); } c++-annotations-12.5.0/yo/concrete/lexer/lexer.ih0000664000175000017500000000010714624637127020513 0ustar frankfrank#include #include "scanner/scanner.h" using namespace std; c++-annotations-12.5.0/yo/concrete/lexer/in.20000644000175000017500000000003014466730207017531 0ustar frankfrankin in.2 #include c++-annotations-12.5.0/yo/concrete/poly2/0000755000175000017500000000000014624637124016775 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/poly2/build0000755000175000017500000000115714466730207020026 0ustar frankfrank#!/bin/bash case "$1" in (prog) cd parser bisonc++ --print-tokens grammar || exit 1 cd ../scanner flexc++ lexer || exit 1 cd .. g++ --std=c++11 -Wall -opoly *.cc */*.cc -lbobcat || exit 1 echo " ready; run the program as './poly < input' " ;; (clean) rm -f poly cd parser rm -f parse.cc parserbase.h cd ../scanner rm -f lex.cc scannerbase.h echo " done " ;; (*) echo " usage: 'build prog' to build the program, 'build clean' to cleanup " exit 1 ;; esac exit 1 c++-annotations-12.5.0/yo/concrete/poly2/input0000644000175000017500000000006114466730207020054 0ustar frankfrankvar = 5 ; var(var, 5, ok, 18); var(5); var(ok); c++-annotations-12.5.0/yo/concrete/poly2/parser/0000755000175000017500000000000014624637124020271 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/poly2/parser/parser.h0000664000175000017500000000221014624637127021736 0ustar frankfrank// Generated by Bisonc++ V3.00.00 on Fri, 24 Feb 2012 15:09:41 +0100 #ifndef Parser_h_included #define Parser_h_included // $insert baseclass #include "parserbase.h" // $insert scanner.h #include "../scanner/scanner.h" #undef Parser class Parser: public ParserBase { // $insert scannerobject Scanner d_scanner; public: int parse(); private: void error(char const *msg); // called on (syntax) errors int lex(); // returns the next token from the // lexical scanner. void print(); // use, e.g., d_token, d_loc void display(STYPE__ const &id, STYPE__ &vect); // support functions for parse(): void executeAction(int ruleNr); void errorRecovery(); int lookup(bool recovery); void nextToken(); void print__(); }; inline void Parser::error(char const *msg) { std::cerr << msg << '\n'; } // $insert lex inline int Parser::lex() { return d_scanner.lex(); } inline void Parser::print() { print__(); // displays tokens if --print was specified } #endif c++-annotations-12.5.0/yo/concrete/poly2/parser/parser.ih0000664000175000017500000000024714624637127022117 0ustar frankfrank // Include this file in the sources of the class Parser. // $insert class.h #include "parser.h" #include using namespace std; using namespace FBB; c++-annotations-12.5.0/yo/concrete/poly2/parser/display.cc0000664000175000017500000000112014624637131022237 0ustar frankfrank#include "parser.ih" void Parser::display(STYPE__ const &id, STYPE__ &vect) { cout << id->as() << "("; char const *sep = ""; for (auto &sp: vect->as()) { cout << sep; switch (sp->tag()) { case Tag::INT: cout << sp->as(); break; case Tag::TEXT: cout << sp->as(); break; default: // Tag::VECTOR intentionally not handled break; } sep = ", "; } cout << ")\n"; } c++-annotations-12.5.0/yo/concrete/poly2/parser/grammar0000644000175000017500000000157514466730207021652 0ustar frankfrank//HEAD %filenames parser %scanner ../scanner/scanner.h %baseclass-preinclude ../spsembase/spsembase.h %stype spSemBase %token INT IDENT //= %% //RULES rules: rules rule | rule ; //= //INT int: INT { $$ = new Semantic(A2x(d_scanner.matched()).to()); } ; ident: IDENT { $$ = new Semantic(d_scanner.matched()); } ; //= //ARGS value: int | ident ; arglist: arglist ',' value { $1->as().push_back($3); } | value { $$ = new Semantic( vector> {$1}); } ; //= //RULE rule: ident '(' arglist ')' ';' { display($1, $3); } | ident '=' int ';' { cout << $1->as() << " = " << $3->as() << ";\n"; } ; //= c++-annotations-12.5.0/yo/concrete/poly2/scanner/0000755000175000017500000000000014624637123020425 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/poly2/scanner/scanner.ih0000664000175000017500000000037414624637127022412 0ustar frankfrank// Declare here // what's only used in the Scanner class // and let Scanner's sources include "scanner.ih" #include "scanner.h" #include "../parser/parserbase.h" // end of scanner.ih c++-annotations-12.5.0/yo/concrete/poly2/scanner/scanner.h0000664000175000017500000000231614624637127022237 0ustar frankfrank// Generated by Flexc++ V0.94.00 on Fri, 24 Feb 2012 15:08:50 +0100 #ifndef Scanner_H_INCLUDED_ #define Scanner_H_INCLUDED_ // $insert baseclass_h #include "scannerbase.h" // $insert classHead class Scanner: public ScannerBase { public: explicit Scanner(std::istream &in = std::cin, std::ostream &out = std::cout); Scanner(std::string const &infile, std::string const &outfile); // $insert lexFunctionDecl int lex(); private: int lex__(); int executeAction__(size_t ruleNr); void print(); void preCode(); // re-implement this function for code that must // be exec'ed before the patternmatching starts }; // $insert scannerConstructors inline Scanner::Scanner(std::istream &in, std::ostream &out) : ScannerBase(in, out) {} inline Scanner::Scanner(std::string const &infile, std::string const &outfile) : ScannerBase(infile, outfile) {} // $insert inlineLexFunction inline int Scanner::lex() { return lex__(); } inline void Scanner::preCode() { // optionally replace by your own code } inline void Scanner::print() { print__(); } #endif // Scanner_H_INCLUDED_ c++-annotations-12.5.0/yo/concrete/poly2/scanner/lexer0000644000175000017500000000035714466730207021475 0ustar frankfrank%filenames scanner %% [[:space:]]+ // skip white space [[:digit:]]+ return Parser::INT; [[:alpha:]_][[:alnum:]_]* return Parser::IDENT; . return matched()[0]; c++-annotations-12.5.0/yo/concrete/poly2/spsembase/0000755000175000017500000000000014624637123020756 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/poly2/spsembase/spsembase.h0000664000175000017500000000055314624637127023122 0ustar frankfrank#ifndef INCLUDED_SPSEMBASE_ #define INCLUDED_SPSEMBASE_ #include "../sembase/sembase.h" class spSemBase: public std::shared_ptr { public: spSemBase() = default; template spSemBase(Type *obj); }; template inline spSemBase::spSemBase(Type *obj) : std::shared_ptr(obj) {} #endif c++-annotations-12.5.0/yo/concrete/poly2/sembase/0000755000175000017500000000000014624637124020414 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/poly2/sembase/sembase.h0000664000175000017500000001540714624637127022220 0ustar frankfrank#ifndef INCLUDED_SEMBASE_ #define INCLUDED_SEMBASE_ #include #include #include #include class SemBase; //TAG enum class Tag // defines the various semantic values { // Tags are used to instantiate the proper INT, // Semantic type, deriving from a polymorphic base TEXT, // class VECTOR, }; //= // In separate anonymous namespace sections parts of the various semantic // types are defined. Sections labeled 'IUO' are `Internal Use Only' and // contain no serviceable parts namespace { // IUO //MUTABLE struct Mutable // Semantic values may or may { // not be mutable. By deriving enum: bool { isMutable = true }; // BasicTrait, below, from }; // either Mutable or Immutable // this trait is associated with struct Immutable // a semantic value BasicTrait. { enum: bool { isMutable = false }; }; //= // For each semantic value type define a TagTrait specialization which // is either derived from Immutable (in which case the Parser cannot // change the semantic value) or from Mutable (In which case changing the // semantic value on the semantic value stack *is* allowed) // In addition, define the data type to use, as received in the // initialization (e.g., int, std::string, vector). //TRAITTAG template struct TagTrait; template <> struct TagTrait: public Immutable { using DataType = int; }; template <> struct TagTrait: public Immutable { using DataType = std::string; }; template <> struct TagTrait: public Mutable { using DataType = std::vector>; }; //= // In this section of the anonymous namespace it is determined whether a // semantic value type is a basic type (in which case the return type of // the Semantic class's conversion operator can be equal to the type // itself) or a class-type (in which case a reference is returned). /// Its logic is based on two function templates 'test' expecting either // any type of argument or expecting a pointer to a member function of the // type provided to the template. Since basic types have no members, the // `any argument' variant is selected by the compiler for basic // types. These two functions return values having different sizes, // allowing the template to determine whether the type is a basic type or // not. The enum value 'isBasicType' is initialized accordingly. /// For the ReturnType (i.e., the conversion operator's return type the // std::conditional template meta programming function is used). For a // mutable data type a reference to the Semantic class's data memebr is // returned, for an immutable basic data type a copy of the data member's // value is returned, otherwise a const & is returned. //CLASSTRAIT struct C2 { char _[2]; }; struct C1 { char _; }; template C1 test(...); template C2 test(void (T::*)()); template struct Trait: public TagTrait { using DataType = typename Trait::DataType; enum: bool { isMutable = Trait::isMutable, isBasicType = sizeof(test(0)) == sizeof(C1) }; using ReturnType = typename std::conditional< isMutable, DataType &, typename std::conditional< isBasicType, DataType, DataType const & >::type >::type; }; //= } /// The implementation of the polymorphic semantic value in fact implements // a type-safe polymorphic semantic union. This is a non-existing data // type in C++, but the parser may handle semantic values as unions: it // always knows the actual type of semantic value that's used at a // particular point in the grammar, and if not, it can inspect the // SemBase's tag fields. Since the parser knows, or can determine what the // actual semantic type is, it can always perform a downcast, resulting in // a *very* lightweight SemBase base class: there's only a virtual // destructor. No other virtual members are required. Downcasting itself // is encapsulated in its 'as' member, allowing constructions like /// $1->as() /// to downcast the $1 SemBase to a Semantic, and then, // usually by implication, to a std::string, using the Semantic's // conversion operator. //SEMBASE class SemBase { Tag d_tag; public: SemBase(SemBase const &other) = delete; virtual ~SemBase(); Tag tag() const; template typename Trait::ReturnType as() const; protected: SemBase(Tag tag); }; //= inline Tag SemBase::tag() const { return d_tag; } inline SemBase::SemBase(Tag tag) : d_tag(tag) {} // The Semantic class template is derived from SemBase. It always defines // its data member as mutable (I can't do this under template control, but // I could define, e.g., two anonymous structs holding, respectively, a // mutable and non-mutable DataType data member, but Semantic isn't doing // anything with d_data anyway, so by always declaring d_data as mutable // it can be returned from the conversion operator, which itself is a // const member. /// Again: Semantic is extremely light-weight. Only initialization and // conversion to the embedded data member need to be supported. //SEMANTIC template class Semantic: public SemBase { using DataType = typename Trait::DataType; enum: bool { isMutable = Trait::isMutable }; mutable DataType d_data; public: using ReturnType = typename Trait::ReturnType; Semantic(DataType const &data); operator ReturnType() const; }; template Semantic::Semantic(DataType const &data) : SemBase(tg_), d_data(data) {} template Semantic::operator ReturnType() const { return d_data; } //= // The 'as' member simply performs the required downcast. It is // implemented here, since it refers to Semantic. Since this class // has just been defined, no forward declaration is required anymore. //AS template inline typename Trait::ReturnType SemBase::as() const { return dynamic_cast const &>(*this); } //= #endif c++-annotations-12.5.0/yo/concrete/poly2/sembase/destructor.cc0000664000175000017500000000005514624637131023121 0ustar frankfrank#include "sembase.h" SemBase::~SemBase() {} c++-annotations-12.5.0/yo/concrete/poly2/main.cc0000664000175000017500000000011214624637131020222 0ustar frankfrank#include "main.ih" int main() { Parser parser; parser.parse(); } c++-annotations-12.5.0/yo/concrete/poly2/main.ih0000664000175000017500000000010214624637127020241 0ustar frankfrank#include #include #include "parser/parser.h" c++-annotations-12.5.0/yo/concrete/header.yo0000644000175000017500000000030214466730207017524 0ustar frankfrank Here is the specification of the header-section of our tt(bison++) specification file. Note the inclusion of the scanner's header file. verbinclude(-a parser/parser/gramspec/header.gr0) c++-annotations-12.5.0/yo/concrete/fdninbuf.yo0000644000175000017500000001024014466730207020071 0ustar frankfrank How complex would things get if we decided to use a buffer of substantial size? Not that complex. The following class allows us to specify the size of a buffer, but apart from that it is basically the same class as tt(IFdStreambuf) developed in the previous section. To make things a bit more interesting, in the class ti(IFdNStreambuf) developed here, the member hi(xsgetn)tt(streambuf::xsgetn) is also overridden, to optimize reading a series of characters. Also a default constructor is provided that can be used in combination with the tt(open) member to construct an tt(istream) object before the file descriptor becomes available. In that case, once the descriptor becomes available, the tt(open) member can be used to initiate the object's buffer. Later, in section ref(FORK), we'll encounter such a situation. To save some space, the success of various calls was not checked. In `real life' implementations, these checks should of course not be omitted. The class tt(IFdNStreambuf) has the following characteristics: itemization( it() Its member functions use low-level functions operating on file descriptors. So apart from tt(streambuf) the tthi(unistd.h) header file must have been read by the compiler before its member functions can be compiled. it() As usual, it is derived from hi(streambuf)tt(std::streambuf). it() Like the class tt(IFdStreambuf) (section ref(IFDBUF)), its data members are protected. Since the buffer's size is configurable, this size is kept in a dedicated data member, tt(d_bufsize): verbinclude(//CLASS examples/ifdnbuf.h) it() The default constructor does not allocate a buffer. It can be used to construct an object before the file descriptor becomes known. A second constructor simply passes its arguments to tt(open). tt(Open) will then initialize the object so that it can actually be used: verbinclude(//CONS examples/ifdnbuf.h) it() Once the object has been initialized by tt(open), its destructor will both delete the object's buffer and use the file descriptor to close the device: verbinclude(//DESTR examples/ifdnbuf.h) Even though the device is closed in the above implementation this may not always be desirable. In cases where the open file descriptor is already available the intention may be to use that descriptor repeatedly, each time using a newly constructed tt(IFdNStreambuf) object. It is left as an exercise to the reader to change this class in such a way that the device may optionally be closed. This approach was followed in, e.g., the url(Bobcat library)(http://fbb-git.gitlab.io/bobcat/). hi(Bobcat library)hi(http://fbb-git.gitlab.io/bobcat/) it() The tt(open) member simply allocates the object's buffer. It is assumed that the calling program has already opened the device. Once the buffer has been allocated, the base class member ti(setg) is used to ensure that hi(eback) tt(streambuf::eback) hi(gptr) tt(streambuf::gptr) and hi(egptr) tt(streambuf::egptr) return correct values: verbinclude(//OPEN examples/ifdnbuf.h) it() The overridden member tt(underflow) is implemented almost identically to tt(IFdStreambuf)'s (section ref(IFDBUF)) member. The only difference is that the current class supports buffers of larger sizes. Therefore, more characters (up to tt(d_bufsize)) may be read from the device at once: verbinclude(//UFLOW examples/ifdnbuf.h) it() Finally ti(xsgetn) is overridden. In a loop, tt(n) is reduced until 0, at which point the function terminates. Alternatively, the member returns if tt(underflow) fails to obtain more characters. This member optimizes the reading of series of characters. Instead of calling hi(sbumpc) tt(streambuf::sbumpc) tt(n) times, a block of tt(avail) characters is copied to the destination, using hi(gbump)tt(streambuf::gbump) to consume tt(avail) characters from the buffer using one function call: verbinclude(//XSGETN examples/ifdnbuf.h) ) The member function ti(xsgetn) is called by hi(sgetn)tt(streambuf::sgetn), which is a tt(streambuf) member. Here is an example illustrating the use of this member function with an tt(IFdNStreambuf) object: verbinclude(-a examples/ifdnbuf.cc) c++-annotations-12.5.0/yo/concrete/codegeneration.yo0000644000175000017500000000205214466730207021266 0ustar frankfrankThe calculator is built using tt(bisonc++) and tt(flexc++). Here is the implementation of the calculator's tt(main) function: verbinclude(-a bisonc++/calculator.cc) The parser's files tt(parse.cc) and tt(parserbase.h) are generated by the command: verb( bisonc++ grammar) The file tt(parser.h) is created only once, to allow the developer to add members to the tt(Parser) class occe the need for them arises. The program ti(flexc++) is used to create a lexical scanner: verb( flexc++ lexer) On i(Unix) systems a command like verb( g++ -Wall -o calc *.cc -lbobcat -s) can be used to compile and link the source of the main program and the sources produced by the scanner and parser generators. The example uses the tt(A2x) class, which is part of the ti(bobcat) library (cf. section ref(BUILDFLEX)) (the bobcat library is available on systems offering either tt(bisonc++) or tt(flexc++)). tt(Bisonc++) can be downloaded from hi(http://fbb-git.gitlab.io/bisoncpp/) tlurl(http://fbb-git.gitlab.io/bisoncpp/). c++-annotations-12.5.0/yo/concrete/sembase.yo0000644000175000017500000000226214466730207017722 0ustar frankfrankThe polymorphic semantic value in fact implements a type-safe hi(union: polymorphic) emi(polymorphic semantic union). In bf(C++) this data type does not exist, but the parser may handle semantic values as unions. It always knows the actual kind of semantic value that's used at a particular point in the grammar. If not, it can inspect tt(SemBase's) tag fields. The parser, knowing what the actual semantic type is, may then perform a i(downcast), resulting in a em(very) lightweight tt(SemBase) base class. The tt(SemBase) class only requires one virtual member: an empty virtual destructor. Downcasting is encapsulated in tt(SemBase)'s 'tt(as)' member. Consequently, the parser, defining its semantic value as an tt(spSembase) (i.e., a tt(shared_ptr) to a tt(Sembase), cf. section ref(BISONSEM)), can then use constructions like verb( $1->as()) to access the tt(std::string) that is stored in the actual semantic value to which tt($1) points. Here is tt(SemBase)'s class interface (the implementation of its `tt(as)' member template follows, implementations of its remaining members are trivial): verbinclude(//SEMBASE poly2/sembase/sembase.h) c++-annotations-12.5.0/yo/concrete/operators.yo0000644000175000017500000000226414466730207020323 0ustar frankfrankIn section ref(OVERLOADBINARY) addition operators are implemented in terms of a support member tt(add). This is less attractive when developing function templates, as tt(add) is a private member, requiring us to provide friend declarations for all function templates so they may access the private tt(add) member. At the end of section ref(OVERLOADBINARY) we saw that tt(add's) implementation can be provided by tt(operator+=(Class const &rhs) &&). This operator may thereupon be used when implementing the remaining addition operators: verb( inline Binary &operator+=(Binary const &rhs) & { return *this = Binary{*this} += rhs; } Binary operator+(Binary &&lhs, Binary const &rhs) { return std::move(lhs) += rhs; } Binary operator+(Binary const &lhs, Binary const &rhs) { return Binary{lhs} += rhs; }) In this implementation tt(add) is no longer required. The plain binary operators are free functions, which supposedly can easily be converted to function templates. E.g., verb( template Binary operator+(Binary const &lhs, Binary const &rhs) { return Binary{lhs} += rhs; }) c++-annotations-12.5.0/yo/concrete/usingflex.yo0000644000175000017500000000400214466730207020301 0ustar frankfrankThe lexical scanner developed in this section is used to monitor the production of a file from several subfiles. The setup is as follows: the input-language defines tt(#include) directives, followed by a text string specifying the file (path) which should be included at the location of the tt(#include). In order to avoid complexities irrelevant to the current example, the format of the tt(#include) statement is restricted to the form tt(#include ). The file specified between the angle brackets should be available at the location indicated by tt(filepath). If the file is not available, the program terminates after issuing an error message. The program is started with one or two filename arguments. If the program is started with just one filename argument, the output is written to the standard output stream tt(cout). Otherwise, the output is written to the stream whose name is given as the program's second argument. The program defines a maximum i(nesting depth). Once this maximum is exceeded, the program terminates after issuing an error message. In that case, the filename stack indicating where which file was included is printed. An additional feature of the program is that (standard bf(C++)) comment-lines are ignored. Include-directives in comment-lines are also ignored. The program is created in five major steps: itemization( it() First, the file tt(lexer) is constructed, containing the input-language specifications. it() From the specifications in tt(lexer) the requirements for the tt(class Scanner) evolve. The tt(Scanner) class derives from the base class ti(ScannerBase) generated by ti(flexc++). it() Next, tt(main) is constructed. A tt(Scanner) object is created inspecting the command-line arguments. If successful, the scanner's member tt(lex) is called to produce the program's output. it() Now that the global setup of the program has been specified, the member functions of the various classes are implemented. it() Finally, the program is compiled and linked. ) c++-annotations-12.5.0/yo/concrete/semantic.yo0000644000175000017500000000221714466730207020106 0ustar frankfrankFinally we reach the class template tt(Semantic), publicly derived from tt(SemBase). This class template only requires one tt(Tag) non-type parameter, defining the kind of data that can be handled by objects of the class. Like tt(SemBase) the class tt(Semantic) is extremely light-weight. Only initialization and a conversion operator to the encapsulated data member must be supported. tt(Semantic) defines its data member as mutable, which is fine as the class itself doesn't manipulate its data, and proper access to the data is guaranteed by its tt(operator ReturnType() const) conversion operator. tt(ReturnType), of course, is obtained through the tt(Trait) trait class template. Here is the class's interface and member definitions: verbinclude(//SEMANTIC poly2/sembase/sembase.h) To access the information stored in a semantic value class the hi(as (SemBase::as)) tt(SemBase::as) member template is used. This member template is provided with a tag value and returns the value stored inside the actual tt(Semantic) object. Its use was shown in the previous section. Here is its implementation: verbinclude(//AS poly2/sembase/sembase.h) c++-annotations-12.5.0/yo/concrete/tagtrait.yo0000644000175000017500000000072514466730207020124 0ustar frankfrankThe ti(TagTrait) trait class defines, for each of the distinct semantic values, what the actual data type (tt(DataType)) is that is associated with the tag and whether the data are mutable or immutable. Mutable data on the parser's semantic stack may be modified, immutable data may not. Here is the tt(TagTrait) meta template struct template and its specializations for the three data types used by our parser. verbinclude(//TRAITTAG poly2/sembase/sembase.h) c++-annotations-12.5.0/yo/concrete/bisonflexspec.yo0000644000175000017500000000067314466730207021153 0ustar frankfrank The flex-specification file used by the calculator is simple: blanks are ignored, single characters are returned, and numeric values are returned as either tt(Parser::INT) or tt(Parser::DOUBLE) tokens. The tt(flexc++) directive tt(%interactive) is provided since the calculator is a program actively interacting with its human user. Here is the complete tt(flexc++) specification file: verbinclude(-a bisonc++/scanner/lexer) c++-annotations-12.5.0/yo/concrete/parser.yo0000644000175000017500000000314714466730207017602 0ustar frankfrankAs noted in the previous section, Bisonc++'s grammar specification declares tt(%stype), the semantic value type, as tt(spSembase). A simple grammar is defined for this illustrative example. The grammar expects input according to the following rule: verb( rule: IDENTIFIER '(' IDENTIFIER ')' ';' | IDENTIFIER '=' INT ';' ;) The rule's actions simply echo the received identifiers and tt(int) values to tt(cout). Here is an example of a decorated production rule, where due to tt(Semantic)'s overloaded insertion operator the insertion of the object controlled by tt(Semantic) is automatically performed: verb( IDENTIFIER '=' INT ';' { cout << $1 << " " << $3 << '\n'; }) Bisonc++'s parser stores em(all) semantic values on its semantic values stack (irrespective of the number of tokens that were defined in a particular production rule). At any time em(all) semantic values associated with previously recognized tokens are available in an action block. Once the semantic value stack is reduced, the tt(Semantic) class's destructor takes care of the proper destruction of the objects controlled by its tt(shared_ptr) base class. In order to assign the parser's latest semantic value, the scanner is given access to that data member, which is the parser's data member tt(d_val__). Its address or reference can be passed to the scanner when it is constructed. E.g., if the scanner's constructor expects an tt(STYPE__ &) argument, then the parser's constructor could simply be implemented as: verb( inline Parser::Parser() : d_scanner(d_val__) {}) c++-annotations-12.5.0/yo/concrete/parents.yo0000644000175000017500000000610414466730207017756 0ustar frankfrank The member function tt(fork) calls the system function tt(fork) (Caution: since the system function tt(fork) is called by a member function having the same name, the tt(::) scope resolution operator must be used to prevent a recursive call of the member function itself). The function tt(::fork)'s return value determines whether tt(parentProcess) or tt(childProcess) is called. Maybe redirection is necessary. tt(Fork::fork)'s implementation calls tt(childRedirections) just before calling tt(childProcess), and tt(parentRedirections) just before calling tt(parentProcess): verbinclude(-a examples/fork.cc) In tt(fork.cc) the class's em(internal header file)hi(internal header) tt(fork.ih) is included. This header file takes care of the inclusion of the necessary system header files, as well as the inclusion of tt(fork.h) itself. Its implementation is: verbinclude(-a examples/fork.ih) Child processes should not return: once they have completed their tasks, they should terminate. This happens automatically when the child process performs a call to a member of the ti(exec...) family, but if the child itself remains active, then it must make sure that it terminates properly. A child process normally uses ti(exit) to terminate itself, but note that tt(exit) prevents the activation of destructors of objects hi(destructor: called at exit) hi(exit: calling destructors) defined at the same or more superficial nesting levels than the level at which tt(exit) is called. Destructors of globally defined objects em(are) activated when tt(exit) is used. When using tt(exit) to terminate tt(childProcess), it should either itself call a support member function defining all nested objects it needs, or it should define all its objects in a compound statement (e.g., using a tt(throw) block) calling tt(exit) beyond the compound statement. Parent processes should normally wait for their children to complete. Terminating child processes inform their parents that they are about to terminate by sending a emi(signal) that should be caught by their parents. If child processes terminate and their parent processes do not catch those signals then such child processes remain visible as so-called emi(zombie) processes. If parent processes must wait for their children to complete, they may call the member tt(waitForChild). This member returns the exit status of a child process to its parent. There exists a situation where the em(child) process em(continues) to live, but the em(parent) dies. This is a fairly natural event: parents tend to die before their children do. In our context (i.e. bf(C++)), this is called a emi(daemon) program. In a daemon the parent process dies and the child program continues to run as a child of the basic ti(init) process. Again, when the child eventually dies a signal is sent to its `step-parent' ti(init). This does not create a zombie as tt(init) catches the termination signals of all its (step-) children. The construction of a daemon process is very simple, given the availability of the class tt(Fork) (cf. section ref(DAEMON)). c++-annotations-12.5.0/yo/concrete/bisonc++/0000755000175000017500000000000014624637124017333 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/bisonc++/build0000755000175000017500000000111514466730207020356 0ustar frankfrank#!/bin/bash case "$1" in ("") echo " usage: 'build prog' to build the program, 'build clean' to cleanup " exit 1 ;; (prog) cd parser bisonc++ grammar || exit 1 cd ../scanner flexc++ lexer || exit 1 cd .. g++ -Wall -ocalc *.cc */*.cc -lbobcat || exit 1 echo " ready; run the program as './calc' " ;; (clean) rm -f calc cd parser rm -f parse.cc parserbase.h cd ../scanner rm -f lex.cc scannerbase.h echo " done " ;; esac exit 1 c++-annotations-12.5.0/yo/concrete/bisonc++/parser/0000755000175000017500000000000014624637124020627 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/bisonc++/parser/parser.h0000664000175000017500000000307714624637127022310 0ustar frankfrank#ifndef Parser_h_included #define Parser_h_included #include #include #include #include "parserbase.h" #include "../scanner/scanner.h" #undef Parser class Parser: public ParserBase { std::ostringstream d_rpn; // $insert scannerobject Scanner d_scanner; public: int parse(); private: template Type exec(char c, Type left, Type right); template Type neg(Type op); template Type convert(); void display(int x); void display(double x); void done() const; void reset(); void error(char const *msg); int lex(); void print(); static double d(int i); // support functions for parse(): void executeAction(int d_ruleNr); void errorRecovery(); int lookup(bool recovery); void nextToken(); void print__(); }; inline double Parser::d(int i) { return i; } template Type Parser::exec(char c, Type left, Type right) { d_rpn << " " << c << " "; return c == '*' ? left * right : left + right; } template Type Parser::neg(Type op) { d_rpn << " n "; return -op; } template Type Parser::convert() { Type ret = FBB::A2x(d_scanner.matched()); d_rpn << " " << ret << " "; return ret; } inline void Parser::error(char const *msg) { std::cerr << msg << '\n'; } inline int Parser::lex() { return d_scanner.lex(); } inline void Parser::print() {} #endif c++-annotations-12.5.0/yo/concrete/bisonc++/parser/display1.cc0000664000175000017500000000023014624637130022656 0ustar frankfrank#include "parser.ih" void Parser::display(int x) { cerr << "RPN: " << d_rpn.str() << '\n'; cerr << "int: " << x << '\n'; d_rpn.str(""s); } c++-annotations-12.5.0/yo/concrete/bisonc++/parser/display2.cc0000664000175000017500000000023614624637130022665 0ustar frankfrank#include "parser.ih" void Parser::display(double x) { cerr << "RPN: " << d_rpn.str() << '\n'; cerr << "double: " << x << '\n'; d_rpn.str(""s); } c++-annotations-12.5.0/yo/concrete/bisonc++/parser/reset.cc0000664000175000017500000000012614624637130022256 0ustar frankfrank#include "parser.ih" void Parser::reset() { d_rpn.clear(); d_rpn.str(""s); } c++-annotations-12.5.0/yo/concrete/bisonc++/parser/parser.ih0000664000175000017500000000055114624637127022453 0ustar frankfrank// include this file in the sources of the class Parser, // and add any includes etc. that are only needed for // the compilation of these sources. // include the file defining the parser class: #include "parser.h" #include #include #include using FBB::A2x; using std::string; using std::cerr; using std::cout; using std::endl; c++-annotations-12.5.0/yo/concrete/bisonc++/parser/grammar0000644000175000017500000000352414466730207022204 0ustar frankfrank//DECLARATION %filenames parser %scanner ../scanner/scanner.h %union { int i; double d; }; %token INT DOUBLE %type intExpr %type doubleExpr %left '+' %left '*' %right UnaryMinus //= %% //RULES lines: lines line | line ; line: intExpr '\n' { display($1); } | doubleExpr '\n' { display($1); } | '\n' { done(); } | error '\n' { reset(); } ; intExpr: intExpr '*' intExpr { $$ = exec('*', $1, $3); } | intExpr '+' intExpr { $$ = exec('+', $1, $3); } | '(' intExpr ')' { $$ = $2; } | '-' intExpr %prec UnaryMinus { $$ = neg($2); } | INT { $$ = convert(); } ; doubleExpr: doubleExpr '*' doubleExpr { $$ = exec('*', $1, $3); } | doubleExpr '*' intExpr { $$ = exec('*', $1, d($3)); } | intExpr '*' doubleExpr { $$ = exec('*', d($1), $3); } | doubleExpr '+' doubleExpr { $$ = exec('+', $1, $3); } | doubleExpr '+' intExpr { $$ = exec('+', $1, d($3)); } | intExpr '+' doubleExpr { $$ = exec('+', d($1), $3); } | '(' doubleExpr ')' { $$ = $2; } | '-' doubleExpr %prec UnaryMinus { $$ = neg($2); } | DOUBLE { $$ = convert(); } ; //= c++-annotations-12.5.0/yo/concrete/bisonc++/parser/done.cc0000664000175000017500000000013414624637130022060 0ustar frankfrank#include "parser.ih" void Parser::done() const { cout << "Good bye\n"; ACCEPT(); } c++-annotations-12.5.0/yo/concrete/bisonc++/scanner/0000755000175000017500000000000014624637123020763 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/bisonc++/scanner/scanner.ih0000664000175000017500000000011514624637127022741 0ustar frankfrank#include "scanner.h" #include "../parser/parserbase.h" // end of scanner.ih c++-annotations-12.5.0/yo/concrete/bisonc++/scanner/scanner.h0000664000175000017500000000170014624637127022571 0ustar frankfrank// Generated by Flexc++ V0.94.00 on Fri, 24 Feb 2012 10:34:13 +0100 #ifndef Scanner_H_INCLUDED_ #define Scanner_H_INCLUDED_ // $insert baseclass_h #include "scannerbase.h" // $insert classHead class Scanner: public ScannerBase { public: explicit Scanner(std::istream &in = std::cin, std::ostream &out = std::cout); // $insert lexFunctionDecl int lex(); private: int lex__(); int executeAction__(size_t ruleNr); void print(); void preCode(); // re-implement this function for code that must // be exec'ed before the patternmatching starts }; // $insert scannerConstructors inline Scanner::Scanner(std::istream &in, std::ostream &out) : ScannerBase(in, out) {} inline void Scanner::preCode() { // optionally replace by your own code } inline void Scanner::print() { print__(); } #endif // Scanner_H_INCLUDED_ c++-annotations-12.5.0/yo/concrete/bisonc++/scanner/lexer0000644000175000017500000000040114466730207022021 0ustar frankfrank%interactive %filenames scanner %% [ \t] // ignored [0-9]+ return Parser::INT; "."[0-9]+ | [0-9]+"."[0-9]* return Parser::DOUBLE; .|\n return matched()[0]; c++-annotations-12.5.0/yo/concrete/bisonc++/calculator.cc0000664000175000017500000000041714624637130021774 0ustar frankfrank#include "parser/parser.h" using namespace std; int main() { Parser parser; cout << "Enter (nested) expressions containing ints, doubles, *, + and " "unary -\n" "operators. Enter an empty line to stop.\n"; return parser.parse(); } c++-annotations-12.5.0/yo/concrete/daemon.yo0000644000175000017500000000221014466730207017537 0ustar frankfrank Applications exist in which the only purpose of ti(fork) is to start a child process. The parent process terminates immediately after spawning the child process. If this happens, the child process continues to run as a child process of ti(init), the always running first process on i(Unix) systems. Such a process is often called a emi(daemon), running as a i(background process). Although the next example can easily be constructed as a plain bf(C) program, it was included in the bf(C++) Annotations because it is so closely related to the current discussion of the tt(Fork) class. I thought about adding a tt(daemon) member to that class, but eventually decided against it because the construction of a daemon program is very simple and requires no features other than those currently offered by the class tt(Fork). Here is an example illustrating the construction of such a daemon program. Its child process doesn't do ti(exit) but tt(throw 0) which is caught by the tt(catch) clause of the child's tt(main) function. Doing this ensures that any objects defined by the child process are properly destroyed: verbinclude(-a examples/daemon.cc) c++-annotations-12.5.0/yo/concrete/redirection.yo0000644000175000017500000000315014466730207020607 0ustar frankfrank Earlier, in section ref(REDIR) streams were hi(redirection) redirected using the hi(rdbuf)tt(ios::rdbuf) member function. By assigning the tt(streambuf) of a stream to another stream, both stream objects access the same tt(streambuf), thus implementing redirection at the level of the programming language itself. This may be fine within the context of a bf(C++) program, but once we leave that context the redirection terminates. The operating system does not know about tt(streambuf) objects. This situation is encountered, e.g., when a program uses a ti(system) call to start a subprogram. The example program at the end of this section uses bf(C++) redirection to redirect the information inserted into ti(cout) to a file, and then calls verb( system("echo hello world")) to echo a well-known line of text. Since tt(echo) writes its information to the standard output, this would be the program's redirected file if the operating system would recognize bf(C++)'s redirection. But redirection doesn't happen. Instead, tt(hello world) still appears at the program's standard output and the redirected file is left untouched. To write tt(hello world) to the redirected file redirection must be realized at the operating system level. Some operating systems (e.g., i(Unix) and friends) provide system calls like ti(dup) and ti(dup2) to accomplish this. Examples of the use of these system calls are given in section ref(PIPE). Here is the example of the em(failing redirection) at the system level following bf(C++) redirection using tt(streambuf) redirection: verbinclude(-a examples/noredir.cc) c++-annotations-12.5.0/yo/concrete/scancompile.yo0000644000175000017500000000125014466730207020574 0ustar frankfrank The final program is constructed in two steps. These steps are given for a i(Unix) system, on which ti(flexc++) and the i(GNU) bf(C++) compiler ti(g++) have been installed: itemization( it() First, the lexical scanner's source is created using tt(flexc++). For this the following command can be given: verb( flexc++ lexer) it() Next, all sources are compiled and linked: verb( g++ -Wall *.cc) ) tt(Flexc++) can be downloaded from hi(https://fbb-git.gitlab.io/flexcpp/) tlurl(https://fbb-git.gitlab.io/flexcpp/), and requires the ti(bobcat) library, which can be downloaded from tlurl(http://fbb-git.gitlab.io/bobcat/). c++-annotations-12.5.0/yo/concrete/fdinseek.yo0000644000175000017500000000516614466730207020101 0ustar frankfrank When devices support em(seek operations), classes derived from hi(streambuf) tt(std::streambuf) should override the members hi(seekoff) tt(streambuf::seekoff) and hi(seekpos)tt(streambuf::seekpos). The class ti(IFdSeek), developed in this section, can be used to read information from devices supporting seek operations. The class tt(IFdSeek) was derived from tt(IFdStreambuf), so it uses a character buffer of just one character. The facilities to perform seek operations, which are added to our new class tt(IFdSeek), ensure that the input buffer is reset when a seek operation is requested. The class could also be derived from the class tt(IFdNStreambuf). In that case the arguments to reset the input buffer must be adapted so that its second and third parameters point beyond the available input buffer. Let's have a look at the characteristics of tt(IFdSeek): itemization( it() As mentioned, tt(IFdSeek) is derived from tt(IFdStreambuf). Like the latter class, tt(IFdSeek)'s member functions use facilities declared in tt(unistd.h). So, the header file tthi(unistd.h) must have been read by the compiler before it can compile the class's members functions. To reduce the amount of typing when specifying types and constants from tt(streambuf) and hi(ios)tt(std::ios), several using-declarations are defined by the class. These using-declarations refer to types that are defined in the header file tthi(ios), which must therefore also be included before the compiler can compile tt(IFdSeek)'s class interface: verbinclude(//CLASS examples/fdinseek.h) it() The class has a very basic interface. Its (only) constructor expects the device's i(file descriptor). It has no special tasks to perform and just calls its i(base class) constructor: verbinclude(//CONS examples/fdinseek.h) it() The member ti(seek_off) is responsible for performing the actual seek operations. It calls ti(lseek) to seek a new position in a device whose file descriptor is known. If seeking succeeds, ti(setg) is called to define an already empty buffer, so that the base class's tt(underflow) member refills the buffer at the next input request. verbinclude(//SEEKOFF examples/fdinseek.h) it() Finally, the companion function ti(seekpos) is overridden as well: it is actually defined as a call to tt(seekoff): verbinclude(//SEEKPOS examples/fdinseek.h) ) Here is an example of a program using the class tt(IFdSeek). If this program is given its own source file using input redirection then seeking is supported (and with the exception of the first line, every other line is shown twice): verbinclude(-a examples/fdinseek.cc) c++-annotations-12.5.0/yo/concrete/lvalues/0000755000175000017500000000000014624637124017403 5ustar frankfrankc++-annotations-12.5.0/yo/concrete/lvalues/lvalues.cc0000664000175000017500000001121014624637131021360 0ustar frankfrank#include #include using namespace std; class Data { friend class Wrapper; // Our Wrapper class is allowed to access our data // too. vector d_v; // here are Data's data public: class Wrapper { Data & d_data; size_t d_index; public: // For all situations in which data[x] is used as lvalue, // an operator must be defined accepting data[x] as lvalue and // all acceptable types as rvalue. Here I've defined two, but // generalizations are straightforward: Wrapper &operator=(Wrapper const &other); // Use our (*this) data as lvalue, the other's data as // rvalue. This is just one situation where our data are // used as lvalue. If data[x] += data[y] is needed too, // then that operator must be defined as well. Wrapper &operator=(int value); // Our data as lvalue. This again is but one example. To // implement data[x] += y etc, those operators must be // overloaded too. // There's only one situation where data[x] is used as rvalue: // when it's returning its data[x] element. This is // accomplished by defining the appropriate conversion // operator: operator int() const; // Our data as rvalue. Can't use things like int &n = // data[3] or int *p = &data[3] here, because the data[3] // expression is parsed as an rvalue, returning an int (in // this case). so if you want to use that, define an // explicit reference and/or pointer returning member, // like int &n = data.ref(3). private: // nobody but Data has anything to do with Wrapper's // constructor so it's made private, declaring Data as its // friend. friend class Data; Wrapper(Data &data, size_t index); }; Data(); int operator[](size_t index) const; // Always rvalue: operator[] of const objects Wrapper operator[](size_t index); // With non-const objects: the Wrapper is returned, to which // a value can be assigned, in which case it's is an lvalue, or // whose value can be requested, in which case the int-conversion // operator is called. }; // I've defined all members inline, although you shouldn't do so in real life. inline Data::Wrapper &Data::Wrapper::operator=(Wrapper const &other) { cout << "data[x] = data[y], lvalue = rvalue\n"; d_data.d_v[d_index] = other.d_data.d_v[other.d_index]; cout << "assignment performed\n"; return *this; } inline Data::Wrapper &Data::Wrapper::operator=(int value) { cout << "data[x] = y, lvalue = expression\n"; d_data.d_v[d_index] = value; return *this; } inline Data::Wrapper::operator int() const { cout << "using the conversion operator, " "returning an rvalue\n"; return d_data.d_v[d_index]; } inline Data::Wrapper::Wrapper(Data &data, size_t index) : d_data(data), d_index(index) {} inline Data::Data() : d_v(5) { for (size_t idx = 0; idx < 5; ++idx) // assign some values d_v[idx] = 2 * idx; } inline int Data::operator[](size_t index) const { cout << "rvalue-only from const object\n"; return d_v[index]; } inline Data::Wrapper Data::operator[](size_t index) { return Wrapper(*this, index); } int main() { Data test; // a non-const object Data const testConst; // a const object (normally via, e.g., a // 'Data const &' parameter // insert some (r)values: cout << "Inserting rvalues:\n" << test[1] << " " << test[2] << "\n\n"; cout << "data[x] to data[y] assignment:\n"; test[1] = test[2]; cout << "Resulting in: " << test[1] << " " << test[2] << "\n\n"; cout << "Assignment from testConst:\n"; test[1] = testConst[4]; cout << "Resulting in: " << test[1] << "\n\n"; cout << "Direct assignment to test[0] (now " << test[0] << ") as an lvalue:\n"; test[0] = 11; cout << "Resulting in: " << test[0] << "\n\n"; cout << "Using test[1] (= " << test[1] << " + 2) in an expression as rvalue\n"; int n = test[1] + 2; } c++-annotations-12.5.0/yo/concrete/shandler.yo0000644000175000017500000000364214466730207020106 0ustar frankfrankThe array tt(s_handler), storing pointers to functions needs to be initialized as well. This can be accomplished in several ways: itemization( it() Since the tt(Commands) enumeration only specifies a fairly limited set of commands, compile-time initialization could be considered: verbinclude(//HANDLER examples/monitor/data.compiletime) The advantage of this is that it's simple, not requiring any run-time effort. The disadvantage is of course relatively complex maintenance. If for some reason tt(Commands) is modified, tt(s_handler) must be modified as well. In cases like these, compile-time initialization often is asking for trouble. There is a simple alternative though. it() Looking at tt(Monitor)'s interface we see a static data member tt(s_initialize) and a static member function tt(initialize). The static member function handles the initialization of the tt(s_handler) array. It explicitly assigns the array's elements and any modification in ordering of tt(enum Commands)' values is automatically accounted for by recompiling tt(initialize): verbinclude(//INIT examples/monitor/monitor.cc) The member tt(initialize) is a static member and so it can be called to initialize tt(s_initialize), a static tt(int) variable. The initialization is enforced by placing the initialization statement in the source file of a function that is known to be executed. It could be tt(main), but if we're tt(Monitor)'s maintainers and only have control over the library containing tt(Monitor)'s code then that's not an option. In those cases the source file containing the destructor is a em(very) good candidate. If a class has only one constructor and it's em(not) defined inline then the constructor's source file is a good candidate as well. In tt(Monitor)'s current implementation the initialization statement is put in tt(run)'s source file, reasoning that tt(s_handler) is only needed when tt(run) is used. ) c++-annotations-12.5.0/yo/concrete/iterators.yo0000644000175000017500000001117214466730207020317 0ustar frankfrankIn section ref(RANDOMIT) the construction of iterators and reverse iterators was discussed. In that section the iterator was constructed as an inner class in a class derived from a vector of pointers to strings. An object of this nested iterator class handles the dereferencing of the pointers stored in the vector. This allowed us to sort the em(strings) pointed to by the vector's elements rather than the em(pointers). A drawback of this is that the class implementing the iterator is closely tied to the derived class as the iterator class was implemented as a nested class. What if we would like to provide any class derived from a container class storing pointers with an iterator handling pointer-dereferencing? In this section a variant of the earlier (nested class) approach is discussed. Here the iterator class is defined as a class template, hi(iterator: as class template) not only parameterizing the data type to which the container's elements point but also the container's iterator type itself. Once again, we concentrate on developing a emi(RandomIterator) as it is the most complex iterator type. Our class is named tt(RandomPtrIterator), indicating that it is a random iterator operating on pointer values. The class template defines three template type parameters: itemization( it() The first parameter specifies the derived class type (tt(Class)). Like before, tt(RandomPtrIterator)'s constructor is private. Therefore tt(friend) declarations are needed to allow client classes to construct tt(RandomPtrIterators). However, a tt(friend class Class) cannot be used as template parameter types cannot be hi(friend: using a template parameter) used in tt(friend class ...) declarations. But this is a minor problem as not every member of the client class needs to construct iterators. In fact, only tt(Class)'s tt(begin) and tt(end) members must construct iterators. Using the template's first parameter, friend declarations can be specified for the client's tt(begin) and tt(end) members. it() The second template parameter parameterizes the container's iterator type (tt(BaseIterator)); it() The third template parameter indicates the data type to which the pointers point (tt(Type)). ) tt(RandomPtrIterator) has one private data member, a tt(BaseIterator). Here is the class interface and the constructor's implementation: verbinclude(//HEAD examples/stringptrs/iterator.h) Looking at its tt(friend) declarations, we see that the members tt(begin) and tt(end) of a class tt(Class), returning a tt(RandomPtrIterator) object for the types tt(Class, BaseIterator) and tt(Type) are granted access to tt(RandomPtrIterator)'s private constructor. That is exactly what we want. The tt(Class)'s tt(begin) and tt(end) members are declared as em(bound friends). All tt(RandomPtrIterator)'s remaining members are public. Since tt(RandomPtrIterator) is just a generalization of the nested class tt(iterator) developed in section ref(RANDOMIT), re-implementing the required member functions is easy and only requires us to change tt(iterator) into tt(RandomPtrIterator) and to change tt(std::string) into tt(Type). For example, tt(operator<), defined in the class tt(iterator) as verbinclude(//CMP ../classtemplates/examples/stringptrs/stringptr.h) is now implemented as: verbinclude(//CMP examples/stringptrs/iterator.h) Some additional examples: tt(operator*), defined in the class tt(iterator) as verbinclude(//OP* ../classtemplates/examples/stringptrs/stringptr.h) is now implemented as: verbinclude(//OP* examples/stringptrs/iterator.h) The pre- and postfix increment operators are now implemented as: verbinclude(//INC examples/stringptrs/iterator.h) Remaining members can be implemented accordingly, their actual implementations are left as exercises to the reader (or can be obtained from the tt(cplusplus.yo.zip) archive, of course). Re-implementing the class tt(StringPtr) developed in section ref(RANDOMIT) is not difficult either. Apart from including the header file defining the class template tt(RandomPtrIterator), it only requires a single modification. Its tt(iterator) using-declaration must now be associated with a tt(RandomPtrIterator). Here is the full class interface and the class's inline member definitions: verbinclude(-a examples/stringptrs/stringptr.h) Including tt(StringPtr)'s modified header file into the program given in section ref(REVERSEIT) results in a program behaving identically to its earlier version. In this case tt(StringPtr::begin) and tt(StringPtr::end) return iterator objects constructed from a template definition. c++-annotations-12.5.0/yo/concrete/fdinbuf.yo0000644000175000017500000000414514466730207017722 0ustar frankfrank When deriving a class (e.g., ti(IFdStreambuf)) from tt(streambuf) using a buffer of one character, at least its member hi(underflow) tt(streambuf::underflow) should be overridden, as this member eventually receives all requests for input. The member hi(setg) tt(streambuf::setg) is used to inform the tt(streambuf) base class of the size and location of the input buffer, so that it is able to set up its input buffer pointers accordingly. This ensures that hi(eback) tt(streambuf::eback), hi(gptr) tt(streambuf::gptr), and hi(egptr) tt(streambuf::egptr) return correct values. The class tt(IFdStreambuf) is designed like this: itemization( it() Its member functions use low-level functions operating on file descriptors. Therefore, in addition to tt(streambuf), the tthi(unistd.h) header file must have been read by the compiler before its member functions can be compiled. it() Like most classes designed for input operations, this class is derived from hi(streambuf)tt(std::streambuf) as well. it() The class defines two data members, one of them a fixed-sized one character buffer. The data members are defined as ti(protected) data members so that derived classes (e.g., see section ref(IFDSEEK)) can access them. Here is the full class interface: verbinclude(//CLASS examples/ifdbuf.h) it() The constructor initializes the buffer. However, the initialization sets ti(gptr)'s return value equal to ti(egptr)'s return value. This implies that the buffer is empty so tt(underflow) is immediately called to fill the buffer: verbinclude(//CONS examples/ifdbuf.h) it() Finally tt(underflow) is overridden. The buffer is refilled by reading from the file descriptor. If this fails (for whatever reason), endOfFile() is returned. More sophisticated implementations could act more intelligently here, of course. If the buffer could be refilled, ti(setg) is called to set up tt(streambuf)'s buffer pointers correctly: verbinclude(//UFLOW examples/ifdbuf.h) ) The following tt(main) function shows how tt(IFdStreambuf) can be used: verbinclude(//MAIN examples/ifdbuf.cc) c++-annotations-12.5.0/yo/concrete/semscanner.yo0000644000175000017500000000042314466730207020436 0ustar frankfrankThe scanner for the polymorphic parser is simple and only needs to recognize numbers, identifiers and some simple characters, returned as character tokens. Here is the scanner's complete specification file, as used by ti(flexc++): verbinclude(-a poly2/scanner/lexer) c++-annotations-12.5.0/yo/inheritance.yo0000644000175000017500000000310514466730207016767 0ustar frankfrankincludefile(inheritance/intro) lsect(VehicleSystem)(Related types) includefile(inheritance/related) subsect(Inheritance depth: desirable?) includefile(inheritance/depth) sect(Access rights: public, private, protected) includefile(inheritance/accessrights) lsubsect(DERIVATIONTYPES)(Public, protected and private derivation) includefile(inheritance/derivationtypes) lsubsect(ACCESSPROMOTION)(Promoting access rights) includefile(inheritance/accessprom) sect(The constructor of a derived class) includefile(inheritance/constructor) subsect(Move construction) includefile(inheritance/move) subsect(Move assignment) includefile(inheritance/assignment) lsubsect(BASECONS)(Inheriting constructors) includefile(inheritance/usingbase) subsect(Aggregate Initializations) includefile(inheritance/aggregate) sect(The destructor of a derived class) includefile(inheritance/destructor) lsect(Truck)(Redefining member functions) includefile(inheritance/redefining) lsect(MULTIPLE)(Multiple inheritance) includefile(inheritance/multiple) sect(Conversions between base classes and derived classes) includefile(inheritance/conversions) subsect(Conversions with object assignments) includefile(inheritance/objectconv) subsect(Conversions with pointer assignments) includefile(inheritance/pointerconv) lsect(NONDEFINIT)(Using non-default constructors with new[]) includefile(inheritance/nondefault) c++-annotations-12.5.0/yo/first/0000755000175000017500000000000014522250255015246 5ustar frankfrankc++-annotations-12.5.0/yo/first/rawstring.yo0000644000175000017500000000640314466730207017651 0ustar frankfrankStandard series of ASCII characters (a.k.a. emi(C strings)) are delimited by double quotes, supporting hi(escape sequence) escape sequences like tt(\n, \\) and tt(\"), and ending in 0-bytes. Such series of ASCII-characters are commonly known as em(null-terminated byte strings) (singular: emi(NTBS), plural: em(NTBSs)). bf(C)'s NTBS is the foundation upon which an enormous amount of code has been built In some cases it is attractive to be able to avoid having to use escape sequences (e.g., in the context of XML). bf(C++) allows this using hi(raw string literal) em(raw string literals). Raw string literals start with an tt(R), followed by a double quote, optionally followed by a label (which is an arbitrary sequence of non-blank characters, followed by tt(OPENPAR)). The raw string ends at the closing parenthesis tt(CLOSEPAR), followed by the label (if specified when starting the raw string literal), which is in turn followed by a double quote. Here are some examples: verb( R"(A Raw \ "String")" R"delimiter(Another \ Raw "(String))delimiter") In the first case, everything between tt("OPENPAR) and tt(CLOSEPAR") is part of the string. Escape sequences aren't supported so the text tt(\ ") within the first raw string literal defines three characters: a backslash, a blank character and a double quote. The second example shows a raw string defined between the markers tt("delimiter)tt(OPENPAR) and tt(CLOSEPARdelimiter"). Raw string literals come in very handy when long, complex ascii-character sequences (e.g., usage-info or long html-sequences) are used. In the end they are just that: long NTBSs. Those long raw string literals should be separated from the code that uses them, thus maintaining the readability of the using code. As an illustration: the bf(bisonc++) parser generator supports an option tt(--prompt). When specified, the code generated by bf(bisonc++) inserts prompting code when debugging is requested. Directly inserting the raw string literal into the function processing the prompting code results in code that is very hard to read: verb( void prompt(ostream &out) { if (d_genDebug) out << (d_options.prompt() ? R"( if (d_debug__) { s_out__ << "\n================\n" "? " << dflush__; std::string s; getline(std::cin, s); } )" : R"( if (d_debug__) s_out__ << '\n'; )" ) << '\n'; }) Readability is greatly enhanced by defining the raw string literals as named NTBSs, defined in the source file's anonymous namespace (cf. chapter ref(NAMESPACE)): verb( namespace { char const noPrompt[] = R"( if (d_debug__) s_out__ << '\n'; )"; char const doPrompt[] = R"( if (d_debug__) { s_out__ << "\n================\n" "? " << dflush__; std::string s; getline(std::cin, s); } )"; } // anonymous namespace void prompt(ostream &out) { if (d_genDebug) out << (d_options.prompt() ? doPrompt : noPrompt) << '\n'; }) c++-annotations-12.5.0/yo/first/unicode.yo0000644000175000017500000000234014466730207017253 0ustar frankfrankIn bf(C++) string literals can be defined as NTBSs. Prepending an NTBS by tt(L) (e.g., tt(L"hello")) defines a tt(wchar_t) string literal. bf(C++) also supports 8, 16 and 32 bit i(Unicode) encoded strings. Furthermore, two new data types are introduced: tt(char16_t) and tt(char32_t) storing, respectively, a ti(UTF-16) and a ti(UTF-32) unicode value. A tt(char) type value fits in a tt(utf_8) unicode value. For character sets exceeding 256 different values wider types (like tt(char16_t) or tt(char32_t)) should be used. String literals for the various types of unicode encodings (and associated variables) can be defined as follows: verb( char utf_8[] = u8"This is UTF-8 encoded."; char16_t utf16[] = u"This is UTF-16 encoded."; char32_t utf32[] = U"This is UTF-32 encoded.";) Alternatively, unicode constants may be defined using the ti(\u) escape sequence, followed by a hexadecimal value. Depending on the type of the unicode variable (or constant) a tt(UTF-8, UTF-16) or tt(UTF-32) value is used. E.g., verb( char utf_8[] = u8"\u2018"; char16_t utf16[] = u"\u2018"; char32_t utf32[] = U"\u2018";) Unicode strings can be delimited by double quotes but raw string literals can also be used. c++-annotations-12.5.0/yo/first/extensions.yo0000644000175000017500000000043414466730207020026 0ustar frankfrankBefore we continue with the `real' object-approach to programming, we first introduce some notable differences with the bf(C) programming language: not mere differences between bf(C) and bf(C++), but important syntactic constructs and keywords not found or differently used in bf(C). c++-annotations-12.5.0/yo/first/examples/0000755000175000017500000000000014624637125017074 5ustar frankfrankc++-annotations-12.5.0/yo/first/examples/bindings.cc0000664000175000017500000000145714624637131021206 0ustar frankfrank#include #include using namespace std; struct Fails { int d_int = 0; double d_double = 0; int (*d_is)(int) = isalnum; private: int d_private; }; struct Data { int d_int = 0; double d_double = 0; int (*d_is)(int) = isalnum; }; int main() { Fails fails; // auto &[i, d, fun, priv] = fails; // won't compile: d_private // is inaccessible // auto &[i, d, fun] = fails; // won't compile: not all of Fails's // members are used Data data; auto &[i, d, fun] = data; // OK // d_int modified through ++i cout << ++i << ' ' << data.d_int << ' ' << fun('a') << ' ' << fun(',') << '\n'; } c++-annotations-12.5.0/yo/first/examples/initializer.cc0000664000175000017500000000045214624637131021726 0ustar frankfrank#include using namespace std; void values(std::initializer_list iniValues) { } void values2(std::initializer_list> iniValues) { } int main() { values({2, 3, 5, 7, 11, 13}); values2({{1, 2}, {2, 3}, {3, 5}, {4, 7}, {5, 11}, {6, 13}}); } c++-annotations-12.5.0/yo/first/examples/rvalueref.cc0000664000175000017500000000265314624637131021403 0ustar frankfrank#include #include using namespace std; template void mswap(T &a, T &b) { T tmp{ std::move(a) }; a = std::move(b); b = std::move(tmp); } struct Data { char *text; void copy(Data const &other) { cout << "A " << (void *)other.text << '\n'; text = strdup(other.text); cout << "B " << (void *)text << '\n'; } void copy(Data &&other) { cout << "D " << (void *)other.text << '\n'; text = other.text; other.text = 0; } }; Data makeData(char const *txt) { Data ret; ret.text = strdup(txt); cout << "C " << (void *)ret.text << '\n'; return ret; } class X { public: X() { cout << "Constructor\n"; } X(X const &other) { cout << "Copycons\n"; } X(X &&other) { cout << "Move constructor\n"; } X &operator=(X const &other) { cout << "std op=\n"; return *this; }; X &operator=(X &&other) { cout << "rref op=\n"; return *this; }; }; X &&fun() { X x; return std::move(x); } int main() { int &&i = int(3); ++i; cout << i << '\n'; Data d1 = { strdup("hello") }; Data d2; d2.copy(d1); cout << "sep\n"; Data d3; d3.copy(makeData("hello")); cout << "sep 2\n"; X &&xr = X(); X x(fun()); // see memory/move.yo: // No initialization of class objects by rvalues yet cout << "sep 3\n"; mswap(xr, x); } c++-annotations-12.5.0/yo/first/examples/structured.cc0000664000175000017500000000055514624637131021613 0ustar frankfrank#include using namespace std; struct Return { int first; double second; }; Return fun() { return Return{1, 12.5}; } Return &fun2() { static Return ret{4, 5}; return ret; } int main() { auto r1 = fun(); cout << r1.first; auto [one, two] = fun(); auto &&[rone, rtwo] = fun(); auto &[lone, ltwo] = fun2(); } c++-annotations-12.5.0/yo/first/examples/byte.cc0000664000175000017500000000124514624637131020347 0ustar frankfrank#include #include #include // uint8_t using namespace std; //ostream &operator<<(ostream &out, uint8_t value) //{ // return out << static_cast(value); //} int main() { // uint8_t u8 = 40; // works great! // cout << u8 << '\n'; //init byte value{ 0x23 }; // #1 (see the text above) // byte error{ 0x123 }; // #2 char ch = 0xfb; // byte error{ ch }; // #3 byte b1 = byte( ch ); // #4 value = byte( 0x123 ); // #5 //= // cout << (value == byte{ 0 }) << '\n'; // cout << hex << static_cast(value) << '\n'; if (value > b1) value &= byte(0xf0); } c++-annotations-12.5.0/yo/first/cvscpp.yo0000644000175000017500000000262414466730207017130 0ustar frankfrankIn this section we'll discuss an important difference between bf(C) and bf(C++) structs and (member) functions. In bf(C) it is common to define several functions to process a tt(struct), which then require a pointer to the tt(struct) as one of their arguments. An imaginary bf(C) header file showing this concept is: verb( /* definition of a struct PERSON This is C */ typedef struct { char name[80]; char address[80]; } PERSON; /* some functions to manipulate PERSON structs */ /* initialize fields with a name and address */ void initialize(PERSON *p, char const *nm, char const *adr); /* print information */ void print(PERSON const *p); /* etc.. */) In bf(C++), the declarations of the involved functions are put inside the definition of the tt(struct) or tt(class). The argument denoting which tt(struct) is involved is no longer needed. verb( class Person { char d_name[80]; char d_address[80]; public: void initialize(char const *nm, char const *adr); void print(); // etc.. };) In bf(C++) the tt(struct) parameter is not used. A bf(C) function call such as: verb( PERSON x; initialize(&x, "some name", "some address");) becomes in bf(C++): verb( Person x; x.initialize("some name", "some address");) c++-annotations-12.5.0/yo/first/datatypes.yo0000644000175000017500000000755414522124434017627 0ustar frankfrankIn bf(C) the following i(built-in) data types are available: tt(void, char, short, int, long, float) and tt(double). bf(C++) extends these built-in types with several additional built-in types: the types ti(bool), ti(wchar_t), ti(long long) and ti(long double) (Cf. i(ANSI/ISO) draft (1995), par. 27.6.2.4.1 for examples of these very long types). The type ti(long long) is merely a double-long tt(long) datatype. The type ti(long double) is merely a double-long tt(double) datatype. These built-in types as well as pointer variables are called emi(primitive types)hi(type: primitive) in the annotations(). There is a subtle issue to be aware of when converting applications developed for 32-bit architectures to 64-bit architectures. When converting 32-bit programs to 64-bit programs, only tt(long) types and pointer types change in size from 32 bits to 64 bits; integers of type tt(int) remain at their size of 32 bits. This may cause data truncation when assigning pointer or tt(long) types to tt(int) types. Also, problems with sign extension can occur when assigning expressions using types shorter than the size of an tt(int) to an tt(unsigned long) or to a pointer. Except for these built-in types the class-type tt(string) is available for handling character strings. The datatypes tt(bool), and tt(wchar_t) are covered in the following sections, the datatype tt(string) is covered in chapter ref(String). Note that recent versions of bf(C) may also have adopted some of these newer data types (notably tt(bool) and tt(wchar_t)). Traditionally, however, bf(C) doesn't support them, hence they are mentioned here. Now that these new types are introduced, let's refresh your memory about em(letters) that can be used in emi(literal constants) of various hi(letters in literal constants) types. They are: itemization( it() ti(b) or tt(B): in addition to its use as a hexadecimal value, it can also be used to define a emi(binary constant). E.g., tt(0b101) equals the decimal value 5. The tt(0b) prefix can be used to specify binary constants starting with the C++14 standard. it() ti(E) or tt(e): hi(literal floating point value using E) the emi(exponentiation) character in floating point literal values. For example: tt(1.23E+3). Here, tt(E) should be pronounced (and interpreted) as: em(times 10 to the power). Therefore, tt(1.23E+3) represents the value tt(1230). it() ti(F) hi(literal float using F) can be used as em(postfix) to a non-integral numeric constant to indicate a value of type tt(float), rather than tt(double), which is the default. For example: tt(12.F) (the dot transforms 12 into a floating point value); tt(1.23E+3F) (see the previous example. tt(1.23E+3) is a tt(double) value, whereas tt(1.23E+3F) is a tt(float) value). it() ti(L) hi(literal wchar_t string L) can be used as em(prefix) to indicate a character string whose elements are tt(wchar_t)-type characters. For example: tt(L"hello world"). it() tt(L) hi(literal long int using L) can be used as em(postfix) to an integral value to indicate a value of type tt(long), rather than tt(int), which is the default. Note that there is no letter indicating a tt(short) type. For that a tt(static_cast()) must be used. it() ti(p), to specify the power hi(power specification using p) in hexadecimal floating point numbers. E.g. tt(0x10p4). The exponent itself is read as a decimal constant and can therefore not start with 0x. The exponent part is interpreted as a power of 2. So tt(0x10p2) is (decimal) equal to 64: tt(16 * 2^2). it() ti(U) hi(literal unsigned using U) can be used as em(postfix) to an integral value to indicate an tt(unsigned) value, rather than an tt(int). It may also be combined with the postfix tt(L) to produce an tt(unsigned long int) value. ) And, of course: the tt(x) and tt(a) until tt(f) characters can be used to specify hexadecimal constants (optionally using capital letters). c++-annotations-12.5.0/yo/first/bitfields.yo0000644000175000017500000000336114466730207017576 0ustar frankfrankBit-fields hi(bit-field) are used to specify series of bits in an integral value type. For example, in networking software processing IP4 packets, the first tt(uint32_t) value of IP4 packets contain: itemization( it() the version (4 bits); it() the header length (4 bits); it() the type of service (8 bits); it() the total length (16 bits) ) Rather than using complex bit and bit-shift operations, these fields inside integral values can be specified using bit-fields. E.g., verb( struct FirstIP4word { uint32_t version: 4; uint32_t header: 4; uint32_t tos: 8; uint32_t length: 16; };) To total size of a tt(FirstIP4word) object is 32 bits, or four bytes. To show the version of a tt(FirstIP4word first) object, simply do: verb( cout << first.version << '\n';) and to set its header length to 10 simply do verb( first.header = 10;) Bit fields are already available in bf(C). The C2a standard allows them to be initialized by default by using initialization expressions in their definitions. E.g., verb( struct FirstIP4word { uint32_t version: 4 = 1; // version now 1, by default uint32_t header: 4 = 10; // TCP header length now 10, by default uint32_t tos: 8; uint32_t length: 16; };) The initialization expressions are evaluated when the object using the bit-fields is defined. Also, when a variable is used to initialize a bit-field the variable must at least have been declared when the struct containing bit-fields is defined. E.g., verb( extern int value; struct FirstIP4word { ... uint32_t length: 16 = value; // OK: value has been declared };) c++-annotations-12.5.0/yo/first/stronglytyped.yo0000644000175000017500000000367014466730207020563 0ustar frankfrankEnumeration values in bf(C++) are in fact tt(int) values, thereby bypassing type safety. E.g., values of different enumeration types may be compared for (in)equality, albeit through a (static) type cast. Another problem with the current tt(enum) type is that their values are not restricted to the enum type name itself, but to the scope where the enumeration is defined. As a consequence, two enumerations having the same scope cannot have identical names. Such problems are solved by defining em(enum classes). An emi(enum class) can be defined as in the following example: verb( enum class SafeEnum { NOT_OK, // 0, by implication OK = 10, MAYBE_OK // 11, by implication };) Enum classes use tt(int) values by default, but the used value type can easily be changed using the tt(: type) notation, as in: verb( enum class CharEnum: unsigned char { NOT_OK, OK };) To use a value defined in an enum class its enumeration name must be provided as well. E.g., tt(OK) is not defined, tt(CharEnum::OK) is. Using the data type specification (noting that it defaults to tt(int)) it is possible to use enum class forward declarations. hi(forward declaration: enum class) E.g., verb( enum Enum1; // Illegal: no size available enum Enum2: unsigned int; // Legal: explicitly declared type enum class Enum3; // Legal: default int type is used enum class Enum4: char; // Legal: explicitly declared type) A sequence of symbols of a strongly typed enumeration can also be indicated in a tt(switch) using the i(ellipsis) syntax, as shown in the next example: verb( SafeEnum enumValue(); switch (enumValue()) { case SafeEnum::NOT_OK ... SafeEnum::OK: cout << "Status is known\n"; break; default: cout << "Status unknown\n"; break; }) c++-annotations-12.5.0/yo/first/public.yo0000644000175000017500000001147314466730207017112 0ustar frankfrankAs mentioned before (see section ref(Pretensions)), bf(C++) contains specialized syntactic possibilities to implement i(data hiding). Data hiding is the capability of sections of a program to hide its data from other sections. This results in very clean data definitions. It also allows these sections to enforce the integrity of their data. bf(C++) has three keywords that are related to data hiding: ti(private), ti(protected) and ti(public). These keywords can be used in the definition of tt(struct)s. The keyword tt(public) allows all subsequent fields of a structure to be accessed by all code; the keyword tt(private) only allows code that is part of the tt(struct) itself to access subsequent fields. The keyword tt(protected) is discussed in chapter ref(INHERITANCE), and is somewhat outside of the scope of the current discussion. In a tt(struct) all fields are tt(public), unless explicitly stated otherwise. Using this knowledge we can expand the tt(struct) tt(Person): verb( struct Person { private: char d_name[80]; char d_address[80]; public: void setName(char const *n); void setAddress(char const *a); void print(); char const *name(); char const *address(); };) As the data fields tt(d_name) and tt(d_address) are in a tt(private) section they are only accessible to the member functions which are defined in the tt(struct): these are the functions tt(setName), tt(setAddress) etc.. As an illustration consider the following code: verb( Person fbb; fbb.setName("Frank"); // OK, setName is public strcpy(fbb.d_name, "Knarf"); // error, x.d_name is private) Data integrity is implemented as follows: the actual data of a tt(struct) tt(Person) are mentioned in the structure definition. The data are accessed by the outside world using special functions that are also part of the definition. These member functions control all traffic between the data fields and other parts of the program and are therefore also called `interface' functions. The thus implemented data hiding is illustrated in fig(datahiding). figure(first/datahiding) (Private data and public interface functions of the class Person.) (datahiding) The members tt(setName) and tt(setAddress) are declared with tt(char const *) parameters. This indicates that the functions will not alter the strings which are supplied as their arguments. Analogously, the members tt(name) and tt(address) return tt(char const *)s: the compiler prevents callers of those members from modifying the information made accessible through the return values of those members. Two examples of member functions of the tt(struct) tt(Person) are shown below: verb( void Person::setName(char const *n) { strncpy(d_name, n, 79); d_name[79] = 0; } char const *Person::name() { return d_name; }) The power of member functions and of the concept of data hiding results from the abilities of member functions to perform special tasks, e.g., checking the validity of the data. In the above example tt(setName) copies only up to 79 characters from its argument to the data member tt(name), thereby avoiding a i(buffer overflow). Another illustration of the concept of data hiding is the following. As an alternative to member functions that keep their data in memory a library could be developed featuring member functions storing data on file. To convert a program storing tt(Person) structures in memory to one that stores the data on disk no special modifications are required. After recompilation and linking the program to a new library it is converted from storage in memory to storage on disk. This example illustrates a broader concept than data hiding; it illustrates emi(encapsulation). Data hiding is a kind of encapsulation. Encapsulation in general results in reduced coupling of different sections of a program. This in turn greatly enhances reusability and maintainability of the resulting software. By having the structure encapsulate the actual storage medium the program using the structure becomes independent of the actual storage medium that is used. Though data hiding can be implemented using tt(struct)s, more often (almost always) em(classes) are used instead. A class is a kind of struct, except that a class uses private access by default, whereas structs use public access by default. The definition of a tt(class) tt(Person) is therefore identical to the one shown above, except that the keyword tt(class) has replaced tt(struct) while the initial tt(private:) clause can be omitted. Our typographic suggestion for class names (and other type names defined by the programmer) is to start with a capital character to be followed by the remainder of the type name using lower case letters (e.g., tt(Person)). c++-annotations-12.5.0/yo/first/sizet.yo0000644000175000017500000000337214466730207016771 0ustar frankfrankThe ti(size_t) type is not really a built-in primitive data type, but a data type that is promoted by bi(POSIX) as a typename to be used for non-negative integral values answering questions like `how much' and `how many', in which case it should be used instead of ti(unsigned int). It is not a specific bf(C++) type, but also available in, e.g., bf(C). Usually it is defined implicitly when a (any) system header file is included. The header file `officially' defining tt(size_t) in the context of bf(C++) is ti(cstddef). Using tt(size_t) has the advantage of being a em(conceptual) type, rather than a standard type that is then modified by a modifier. Thus, it improves the self-documenting value of source code. Several suffixes can be used to expicitly specify the intended representation of integral constants, like tt(42UL) defining 42 as an tt(unsigned long int). Likewise, suffixes ti(uz) or tt(zu) can be used to specify that an integral constant is represented as a tt(size_t), as in: tt(cout << 42uz). Sometimes functions explictly require tt(unsigned int) to be used. E.g., on ti(amd)-architectures the i(X-windows) function ti(XQueryPointer) explicitly requires a pointer to an tt(unsigned int) variable as one of its arguments. In such situations a pointer to a tt(size_t) variable can't be used, but the address of an tt(unsigned int) must be provided. Such situations are exceptional, though. Other useful bit-represented types also exists. E.g., ti(uint32_t) is guaranteed to hold 32-bits unsigned values. Analogously, ti(int32_t) holds 32-bits signed values. Corresponding types exist for 8, 16 and 64 bits values. These types are defined in the header file ti(cstdint) and can be very useful when you need to specify or use integral value types of fixed sizes. c++-annotations-12.5.0/yo/first/using.yo0000644000175000017500000000510414466730207016753 0ustar frankfrankIn bf(C++) tt(typedef) is commonly used to define shorthand notations for complex types. Assume we want to define a shorthand for `a pointer to a function expecting a double and an int, and returning an unsigned long long int'. Such a function could be: verb( unsigned long long int compute(double, int);) A pointer to such a function has the following form: verb( unsigned long long int (*pf)(double, int);) If this kind of pointer is frequently used, consider defining it using tt(typedef): simply put tt(typedef) in front of it and the pointer's name is turned into the name of a type. It could be capitalized to let it stand out more clearly as the name of a type: verb( typedef unsigned long long int (*PF)(double, int);) After having defined this type, it can be used to declare or define such pointers: verb( PF pf = compute; // initialize the pointer to a function like // 'compute' void fun(PF pf); // fun expects a pointer to a function like // 'compute') However, including the pointer in the typedef might not be a very good idea, as it masks the fact that tt(pf) is a pointer. After all, tt(PF pf) looks more like `tt(int x)' than `tt(int *x)'. To document that tt(pf) is in fact a pointer, slightly change the tt(typedef): verb( typedef unsigned long long int FUN(double, int); FUN *pf = compute; // now pf clearly is a pointer.) The scope of typedefs is restricted to compilation units. Therefore, typedefs are usually embedded in header files which are then included by multiple source files in which the typedefs should be used. In addition to tt(typedef) bf(C++) offers the ti(using) keyword to associate a type and an identifier. In practice tt(typedef) and tt(using) can be used interchangeably. The tt(using) keyword arguably result in more readable type definitions. Consider the following three (equivalent) definitions: itemization( it() The traditional, bf(C) style definition of a type, embedding the type name in the definition (turning a variable name into a type name): verb(typedef unsigned long long int FUN(double, int);) it() Apply tt(using) to improve the visibility (for humans) of the type name, by moving the type name to the front of the definition: verb(using FUN = unsigned long long int (double, int);) it() An alternative construction, using a late-specified return type (cf. section ref(AUTO)): verb(using FUN = auto (double, int) -> unsigned long long int;) ) c++-annotations-12.5.0/yo/first/staticcast.yo0000644000175000017500000000716414466730207020000 0ustar frankfrankThe hi(static_cast)tt(static_cast(expression)) is used to convert `conceptually comparable or related types' to each other. Here as well as in other bf(C++) style casts tt(type) is the type to which the type of tt(expression) should be cast. Here are some examples of situations where the tt(static_cast) can (or should) be used: itemization( it() When converting an tt(int) to a tt(double). nl() This happens, for example when the quotient of two tt(int) values must be computed without losing the fraction part of the division. The tt(sqrt) function called in the following fragment returns 2: verb(int x = 19; int y = 4; sqrt(x / y);) whereas it returns 2.179 when a tt(static_cast) is used, as in: verb(sqrt(static_cast(x) / y);) The important point to notice here is that a tt(static_cast) is allowed to change the representation of its tt(expression) into the representation that's used by the destination type. Also note that the division is put outside of the cast expression. If the division is performed within the cast's tt(expression) (as in tt(static_cast(x / y))) an emi(integer division) has already been performed em(before) the cast has had a chance to convert the type of an operand to tt(double). it() When converting tt(enum) values to tt(int) values (in any direction). nl() Here the two types use identical representations, but different semantics. Assigning an ordinary tt(enum) value to an tt(int) doesn't require a cast, but when the enum is a em(strongly typed enum) a cast em(is) required. Conversely, a tt(static_cast) is required when assigning an tt(int) value to a variable of some enum type. Here is an example: verb(enum class Enum { VALUE }; cout << static_cast(Enum::VALUE); // show the numeric value) it() When converting related pointers to each other.nl() The tt(static_cast) is used in the context of class inheritance (cf. chapter ref(INHERITANCE)) to convert a pointer to a so-called `derived class' to a pointer to its `base class'. It cannot be used for casting unrelated types to each other (e.g., a tt(static_cast) can+em(not) be used to cast a pointer to a tt(short) to a pointer to an tt(int)). A tt(void *) is a em(generic pointer). It is frequently used by functions in the bf(C) library (e.g., bf(memcpy)(3)). Since it is the generic pointer it is related to any other pointer, and a tt(static_cast) should be used to convert a tt(void *) to an intended destination pointer. This is a somewhat awkward left-over from bf(C), which should probably only be used in that context. Here is an example: The tt(qsort) function from the bf(C) library expects a pointer to a (comparison) function having two tt(void const *) parameters. In fact, these parameters point to data elements of the array to be sorted, and so the comparison function must cast the tt(void const *) parameters to pointers to the elements of the array to be sorted. So, if the array is an tt(int array[]) and the compare function's parameters are tt(void const *p1) and tt(void const *p2) then the compare function obtains the address of the tt(int) pointed to by tt(p1) by using: verb(static_cast(p1);) it() When undoing or introducing the signed-modifier of an tt(int)-typed variable (remember that a tt(static_cast) is allowed to change the expression's representation!). nl() Here is an example: the bf(C) function tt(tolower) requires an tt(int) representing the value of an tt(unsigned char). But tt(char) by default is a signed type. To call tt(tolower) using an available tt(char ch) we should use: verb( tolower(static_cast(ch))) ) c++-annotations-12.5.0/yo/first/initializer.yo0000644000175000017500000000610514466730207020153 0ustar frankfrankThe bf(C) language defines the i(initializer list) as a list of values enclosed by curly braces, possibly themselves containing initializer lists. In bf(C) these initializer lists are commonly used to initialize arrays and structs. bf(C++) extends this concept by introducing the em(type) tt(initializer_list) where tt(Type) is replaced by the type name of the values used in the initializer list. Initializer lists in bf(C++) are, like their counterparts in bf(C), recursive, so they can also be used with multi-dimensional arrays, structs and classes. Before using the tt(initializer_list) the tthi(initializer_list) header file must be included. Like in bf(C), initializer lists consist of a list of values surrounded by curly braces. But unlike bf(C), em(functions) can define initializer list parameters. E.g., verb( void values(std::initializer_list iniValues) { }) A function like tt(values) could be called as follows: verb( values({2, 3, 5, 7, 11, 13});) The initializer list appears as an argument which is a list of values surrounded by curly braces. Due to the recursive nature of initializer lists a two-dimensional series of values can also be passes, as shown in the next example: verb( void values2(std::initializer_list> iniValues) {} values2({{1, 2}, {2, 3}, {3, 5}, {4, 7}, {5, 11}, {6, 13}});) Initializer lists are constant expressions and cannot be modified. However, their em(size) and values may be retrieved using their tt(size, begin), and tt(end) members as follows: verb( void values(initializer_list iniValues) { cout << "Initializer list having " << iniValues.size() << "values\n"; for ( initializer_list::const_iterator begin = iniValues.begin(); begin != iniValues.end(); ++begin ) cout << "Value: " << *begin << '\n'; }) Initializer lists can also be used to initialize objects of classes (cf. section ref(UNIFORMINIT), which also summarizes the facilities of initializer lists). em(Implicit conversions), also called em(narrowing conversions) hi(narrowing conversion) are not allowed when specifying values of initializer lists. Narrowing conversions are encountered when values are used of a type whose range is larger than the type specified when defining the initializer list. For example itemization( it() specifying tt(float) or tt(double) values to define initializer lists of tt(int) values; it() specifying integral values exceeding the range of tt(float) to define initializer lists of tt(float) values; it() specifying values of integral types of a wider range than the integral type that is specified for the initializer list, except if the specified values lie within the range of the initializer list's integral type ) Some examples: verb( initializer_list ii{ 1.2 }; // 1.2 isn't an int value initializer_list iu{ ~0ULL }; // unsigned long long doesn't fit ) c++-annotations-12.5.0/yo/first/binding.yo0000644000175000017500000001022114466730207017234 0ustar frankfrankUsually functions return single-valued results: tt(doubles, ints, strings), etc. When functions need to return multiple values a em(return by argument) construction is often used, where addresses of variables that live outside of the called function are passed to functions, allowing the functions to assign new values to those variables. When multiple values should be em(returned) from a function a tt(struct) can be used, but em(pairs) (cf. section ref(PAIR)) or em(tuples) (cf. section ref(TUPLES)) can also be used. Here's a simple example, where a function tt(fun) returns a tt(struct) having two data fields: verb( struct Return { int first; double second; }; Return fun() { return Return{ 1, 12.5 }; }) (Briefly forward referencing to sections ref(PAIR) and ref(TUPLES): the tt(struct) definition can completely be omitted if tt(fun) returns a tt(pair) or tt(tuple). In those cases the following code remains valid.) A function em(calling) tt(fun) traditionally defines a variable of the same type as tt(fun's) return type, and then uses that variable's fields to access tt(first) and tt(second). If you don't like the typing, tt(auto) can also be used: verb( int main() { auto r1 = fun(); cout << r1.first; }) Instead of referring to the elements of the returned tt(struct, pair) or tt(tuple) em(structured binding declarations) can also be used. Here, tt(auto) is followed by a (square brackets surrounded) comma-separated list of variables, where each variable is em(defined), and receives the value of the corresponding field or element of the called function's return value. So, the above tt(main) function can also be written like this: verb( int main() { auto [one, two] = fun(); cout << one; // one and two: now defined }) Merely specifying tt(auto) results in tt(fun's) return value being copied, and the structured bindings variables will refer to the copied value. But structured binding declarations can also be used in combination with (lvalue/rvalue) return values. The following ensures that tt(rone) and tt(rtwo) refer to the elements of tt(fun's) anonymous return value: verb( int main() { auto &&[rone, rtwo] = fun(); }) If the called function returns a value that survives the function call itself, then structured binding declarations can use em(lvalue references). E.g., verb( Return &fun2() { static Return ret{ 4, 5 }; return ret; } int main() { auto &[lone, ltwo] = fun2(); // OK: referring to ret's fields }) To use structured binding declarations it is not required to use function calls. The object providing the data can also anonymously be defined: verb( int main() { auto const &[lone, ltwo] = Return{ 4, 5 }; // or: auto &&[lone, ltwo] = Return{ 4, 5 }; }) The object doesn't even have to make its data members publicly available. In section tt(TUPLES) using structured bindings not necessarily referring to data members is covered. Another application is found in situations where nested statements of tt(for) or selection statements benefit from using locally defined variables of various types. Such variables can easily be defined using structured binding declarations that are initialized from anonymous structs, pairs or tuples. Here is an example illustrating this: verb( // define a struct: struct Three { size_t year; double firstAmount; double interest; }; // define an array of Three objects, and process each in turn: Three array[10]; fill(array); // not implemented here for (auto &[year, amount, interest]: array) cout << "Year " << year << ": amount = " << amount << '\n';) When using structured bindings the structured binding declaration must specify all elements that are available. So if a struct has four data members the structured binding declaration must define four elements. To avoid warnings of unused variables at lease one of the variables of the structured binding declaration must be used. c++-annotations-12.5.0/yo/first/spaceship.yo0000644000175000017500000000125014522124711017571 0ustar frankfrankThe C2a standard added the em(three-way comparison) operator tt(<=>), also known as the em(spaceship operator), to bf(C++). In bf(C++) operators can be defined for class-types, among which equality and comparison operators (the familiar set of tt(==, !=, <, <=, >) and tt(>=) operators). To provide classes with all comparison operators merely the equality and the spaceship operator need to be defined. Its priority hi(<=>: priority) is less than the priorities of the bit-shift operators tt(<<) and tt(>>) and larger than the priorities of the ordering operators tt(<, <=, >,) and tt(>=). Section ref(SPACESHIP) covers the construction of the three-way comparison operator. c++-annotations-12.5.0/yo/first/rangebased.yo0000644000175000017500000001032214466730207017717 0ustar frankfrankThe bf(C++) for-statement is identical to bf(C)'s for-statement: verb( for (init; cond; inc) statement) Often the initialization, condition, and increment parts are fairly obvious, as in situations where all elements of an array or vector must be processed. Many languages offer the tt(foreach) statement for that and bf(C++) offers the tt(std::for_each) generic algorithm (cf. section ref(FOREACH)). In addition to the traditional syntax bf(C++) adds new syntax for the tt(for)-statement: the emi(range-based for-loop). This new syntax can be used to process all element of a i(range) in turn. Three types of ranges are distinguished: itemization( it() Plain arrays (e.g., tt(int array[10])); it() Initializer lists; it() Standard containers (or comparable) (cf. chapter ref(CONTAINERS)); it() Any other type offering tt(begin()) and tt(end()) functions returning so-called em(iterators) (cf. section ref(ITERATORS)). ) The following additional i(for-statement) syntax is available: verb( // assume int array[30] for (auto &element: array) statement) The part to the left of the colon is called the emi(for range declaration). The declared variable (tt(element)) is a formal name; use any identifier you like. The variable is only available within the nested statement, and it refers to (or is a copy of) each of the elements of the range, from the first element up to the last. There's no formal requirement to use tt(auto), but using tt(auto) is extremely useful in many situations. Not only in situations where the range refers to elements of some complex type, but also in situations where you know what you can do with the elements in the range, but don't care about their exact type names. In the above example tt(int) could also have been used. The reference symbol (tt(&)) is important in the following cases: itemization( it() if you want to modify the elements in the nested statements it() if the elements themselves are tt(struct)s (or em(classes), cf. chapter ref(Classes)) ) When the reference symbol is omitted the variable will be a copy of each of the subsequent elements of the range. Fine, probably, if you merely need to look at the variables when they are of primitive types, but needlessly inefficient if you have an array of tt(BigStruct) elements: verb( struct BigStruct { double array[100]; int last; };) Inefficient, because you don't need to make copies of the array's elements. Instead, use references to elements: verb( BigStruct data[100]; // assume properly initialized elsewhere int countUsed() { int sum = 0; // const &: the elements aren't modified for (auto const &element: data) sum += element.last; return sum; }) Range-based for-loops can also benefit from structured bindings. If tt(struct Element) holds a tt(int key) and a tt(double value), and all the values of positive keys should be added then the following code snippet accomplishes that: verb( Element elems[100]; // somehow initialized double sum = 0; for (auto const &[key, value]: elems) { if (key > 0) sum += value; }) The C2a standard also supports an optional initialization section (like the ones already available for tt(if) and tt(switch) statements) for range-based for-loops. Assume the elements of an array must be inserted into tt(cout), but before each element we want to display the element's index. The index variable is not used outside the tt(for)-statement, and the extension offered in the C2a standard allows us to localize the index variable. Here is an example: verb( // localize idx: only visible in the for-stmnt for (size_t idx = 0; auto const &element: data) cout << idx++ << ": " << element << '\n';) COMMENT( If tt(data) is only available as a pointer to its first element in combination with the number of elements, range-based for loops can also be used, but require a little help. Section ref(RANGER) describes a generic approach to using range based for loops in such cases. END) c++-annotations-12.5.0/yo/first/reinterpretcast.yo0000644000175000017500000000523314466730207021047 0ustar frankfrankThe third new-style cast is used to change the em(interpretation) of information: the tt(reinterpret_cast). It is somewhat reminiscent of the tt(static_cast), but tt(reinterpret_cast) should only be used when it is em(known) that the information as defined in fact is or can be interpreted as something completely different. Its syntax is: verb( reinterpret_cast(pointer expression)) Think of the tt(reinterpret_cast) as a cast offering a poor-man's union: the same memory location may be interpreted in completely different ways. The tt(reinterpret_cast) is used, for example, in combination with the tt(write) function that is available for em(streams). In bf(C++) streams are the preferred interface to, e.g., disk-files. The standard streams like tt(std::cin) and tt(std::cout) also are stream objects. Streams intended for writing (`output streams' like tt(cout)) offer tt(write) members having the prototype verb( write(char const *buffer, int length)) To write the value stored within a tt(double) variable to a stream in its un-interpreted binary form the stream's tt(write) member is used. However, as a tt(double *) and a tt(char *) point to variables using different and unrelated representations, a tt(static_cast) cannot be used. In this case a tt(reinterpret_cast) is required. To write the raw bytes of a variable tt(double value) to tt(cout) we use: verb( cout.write(reinterpret_cast(&value), sizeof(double));) All casts are potentially dangerous, but the tt(reinterpret_cast) is the most dangerous of them all. Effectively we tell the compiler: back off, we know what we're doing, so stop fuzzing. All bets are off, and we'd better em(do) know what we're doing in situations like these. As a case in point consider the following code: verb( int value = 0x12345678; // assume a 32-bits int cout << "Value's first byte has value: " << hex << static_cast( *reinterpret_cast(&value) );) The above code produces different results on little and big endian computers. Little endian computers show the value 78, big endian computers the value 12. Also note that the different representations used by little and big endian computers renders the previous example (tt(cout.write(...))) non-portable over computers of different architectures. As a i(rule of thumb): if circumstances arise in which casts em(have) to be used, clearly document the reasons for their use in your code, making double sure that the cast does not eventually cause a program to misbehave. Also: avoid tt(reinterpret_casts) unless you em(have) to use them. c++-annotations-12.5.0/yo/first/wchar.yo0000644000175000017500000000102414466730207016727 0ustar frankfrankThe ti(wchar_t) type is an extension of the tt(char) built-in type, to accommodate em(wide) character values (but see also the next section). The tt(g++) compiler reports tt(sizeof(wchar_t)) as 4, which easily accommodates all 65,536 different em(Unicode) character values. Note that bf(Java)'s tt(char) data type is somewhat comparable to bf(C++)'s tt(wchar_t) type. bf(Java)'s tt(char) type is 2 bytes wide, though. On the other hand, bf(Java)'s tt(byte) data type is comparable to bf(C++)'s tt(char) type: one byte. Confusing? c++-annotations-12.5.0/yo/first/keywords.yo0000644000175000017500000000565514466730207017510 0ustar frankfrankbf(C++)'s i(keywords) are a superset of bf(C)'s keywords. Here is a list of all keywords of the language: COMMENT(table generated by src/keywordsort.cc (using -lbobcat)) verb(alignas char16_t double long reinterpret_cast true alignof char32_t dynamic_cast module requires try and class else mutable return typedef and_eq co_await enum namespace short typeid asm co_return explicit new signed typename atomic_cancel co_yield export noexcept sizeof union atomic_commit compl extern not static unsigned atomic_noexcept concept false not_eq static_assert using auto const float nullptr static_cast virtual bitand const_cast for operator struct void bitor constexpr friend or switch volatile bool continue goto or_eq synchronized wchar_t break decltype if private template while case default import protected this xor catch delete inline public thread_local xor_eq char do int register throw) Notes: itemization( COMMENT( it() The ti(export) keyword is no longer actively used by bf(C++), but it is kept as a keyword, reserved for future use. END) it() Since the i(C++17) standard the keyword ti(register) is no longer used, but it remains a reserved identifier. In other words, definitions like verb( register int index;) result in compilation errors. Also, tt(register) is no longer considered a i(storage class specifier) (storage class specifiers are tt(extern, thread_local, mutable) and tt(static)). it() the hi(operator: keywords)em(operator keywords): tt( and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor) and tt(xor_eq) are symbolic alternatives for, respectively, tt(&&, &=, &, |, ~, !, !=, ||, |=, ^) and tt(^=). it() bf(C++) also recognizes the special identifiers tt(final, override, transaction_safe), and tt(transaction_safe_override). These identifiers are special in the sense that they acquire special meanings when declaring classes or polymorphic functions. Section ref(FINAL) provides further details. ) Keywords can only be used for their intended purpose and cannot be used as names for other entities (e.g., variables, functions, class-names, etc.). In addition to keywords i(identifiers starting with an underscore) and living in the emi(global namespace) (i.e., not using any explicit namespace or using the mere tt(::) namespace specification) or living in the em(std namespace) are i(reserved identifiers) in the sense that their use is a prerogative of the implementor. c++-annotations-12.5.0/yo/first/bool.yo0000644000175000017500000000514714466730207016570 0ustar frankfrank The type tt(bool) represents boolean (logical) values, for which the (now reserved) constants ti(true) and ti(false) may be used. Except for these reserved values, integral values may also be assigned to variables of type tt(bool), which are then implicitly converted to tt(true) and tt(false) according to the following i(conversion rules) (assume tt(intValue) is an tt(int)-variable, and tt(boolValue) is a tt(bool)-variable): verb( // from int to bool: boolValue = intValue ? true : false; // from bool to int: intValue = boolValue ? 1 : 0;) Furthermore, when tt(bool) values are inserted into streams then tt(true) is represented by tt(1), and tt(false) is represented by tt(0). Consider the following example: verb( cout << "A true value: " << true << "\n" "A false value: " << false << '\n';) The tt(bool) data type is found in other programming languages as well. bf(Pascal) has its type tt(Boolean); bf(Java) has a tt(boolean) type. Different from these languages, bf(C++)'s type tt(bool) acts like a kind of tt(int) type. It is primarily a documentation-improving type, having just two values tt(true) and tt(false). Actually, these values can be interpreted as tt(enum) values for tt(1) and tt(0). Doing so would ignore the philosophy behind the tt(bool) data type, but nevertheless: assigning tt(true) to an tt(int) variable neither produces warnings nor errors. Using the tt(bool)-type is usually clearer than using tt(int). Consider the following prototypes: verb( bool exists(char const *fileName); // (1) int exists(char const *fileName); // (2)) With the first prototype, readers expect the function to return tt(true) if the given filename is the name of an existing file. However, with the second prototype some ambiguity arises: intuitively the return value 1 is appealing, as it allows constructions like verb( if (exists("myfile")) cout << "myfile exists";) On the other hand, many system functions (like ti(access), ti(stat), and many other) return 0 to indicate a successful operation, reserving other values to indicate various types of errors. As a rule of thumb I suggest the following: if a function should inform its caller about the success or failure of its task, let the function return a tt(bool) value. If the function should return success or various types of errors, let the function return em(enum) values, documenting the situation by its various symbolic constants. Only when the function returns a conceptually meaningful integral value (like the sum of two tt(int) values), let the function return an tt(int) value. c++-annotations-12.5.0/yo/first/namespaces.yo0000644000175000017500000000161014466730207017743 0ustar frankfrankbf(C++) introduces the notion of a emi(namespace): all symbols are defined in a larger context, called a em(namespace). Namespaces are used to avoid i(name conflicts) that could arise when a programmer would like to define a function like tt(sin) operating on em(degrees), but does not want to lose the capability of using the standard tt(sin) function, operating on em(radians). Namespaces are covered extensively in chapter ref(NAMESPACE). For now it should be noted that most compilers require the explicit declaration of a emi(standard namespace): tt(std). So, unless otherwise indicated, it is stressed that all examples in the Annotations now implicitly use the hi(using namespace std) verb( using namespace std;) declaration. So, if you actually intend to compile examples given in the annotations(), make sure that the sources start with the above tt(using) declaration. c++-annotations-12.5.0/yo/first/longlongint.yo0000644000175000017500000000014414466730207020157 0ustar frankfrankbf(C++) also supports the type ti(long long int). On 32 bit systems it has at least 64 usable bits. c++-annotations-12.5.0/yo/first/selectinit.yo0000644000175000017500000000327014522124632017763 0ustar frankfrankThe standard tt(for) repetition statements start with an optional initialization clause. The initialization clause allows us to localize variables to the scope of the for statements. Initialization clauses can also be used in selection statements. Consider the situation where an action should be performed if the next line read from the standard input stream equals tt(go!). Traditionally, when used inside a function, intending to localize the string to contain the content of the next line as much as possible, constructions like the following had to be used: verb( void function() { // ... any set of statements { string line; // localize line if (getline(cin, line)) action(); } // ... any set of statements }) Since tt(init ;) clauses can also be used for selection statements (tt(if) and tt(switch) statements) (note that with selection statements the semicolon is part of the initialization clause, which is different from the optional tt(init) (no semicolon) clause in tt(for) statements), we can rephrase the above example as follows: verb( void function() { // ... any set of statements if (string line; getline(cin, line)) action(); // ... any set of statements }) Note that a variable may still also be defined in the actual condition clauses. This is true for both the extended tt(if) and tt(switch) statement. However, before using the condition clauses an initialization clause may be used to define additional variables (plural, as it may contain a comma-separated list of variables, similar to the syntax that's available for tt(for)-statements). c++-annotations-12.5.0/yo/first/rvalueref.yo0000644000175000017500000001561414466730207017630 0ustar frankfrankIn bf(C++), temporary (rvalue) values are indistinguishable from tt(const &) types. bf(C++) introduces a new reference type called an emi(rvalue reference), which is defined as ti(typename &&). The name em(rvalue) reference is derived from assignment statements, where the variable to the left of the assignment operator is called an emi(lvalue) and the expression to the right of the assignment operator is called an emi(rvalue). Rvalues are often temporary, anonymous values, like values returned by functions. In this parlance the bf(C++) reference should be considered an emi(lvalue reference) (using the notation tt(typename &)). They can be contrasted to em(rvalue references) (using the notation tt(typename &&)). The key to understanding rvalue references is the concept of an emi(anonymous variable). An anonymous variable has no name and this is the distinguishing feature for the compiler to associate it automatically with an rvalue reference if it has a choice. Before introducing some interesting constructions let's first have a look at some standard situations where em(lvalue) references are used. The following function returns a temporary (anonymous) value: verb( int intVal() { return 5; }) Although tt(intVal)'s return value can be assigned to an tt(int) variable it requires copying, which might become prohibitive when a function does not return an tt(int) but instead some large object. A em(reference) or em(pointer) cannot be used either to collect the anonymous return value as the return value won't survive beyond that. So the following is illegal (as noted by the compiler): verb( int &ir = intVal(); // fails: refers to a temporary int const &ic = intVal(); // OK: immutable temporary int *ip = &intVal(); // fails: no lvalue available) Apparently it is not possible to modify the temporary returned by tt(intVal). But now consider these functions: verb( void receive(int &value) // note: lvalue reference { cout << "int value parameter\n"; } void receive(int &&value) // note: rvalue reference { cout << "int R-value parameter\n"; }) and let's call this function from tt(main): verb( int main() { receive(18); int value = 5; receive(value); receive(intVal()); }) This program produces the following output: verb( int R-value parameter int value parameter int R-value parameter) The program's output shows the compiler selecting tt(receive(int &&value)) in all cases where it receives an anonymous tt(int) as its argument. Note that this includes tt(receive(18)): a value 18 has no name and thus tt(receive(int &&value)) is called. Internally, it actually uses a temporary variable to store the 18, as is shown by the following example which modifies tt(receive): verb( void receive(int &&value) { ++value; cout << "int R-value parameter, now: " << value << '\n'; // displays 19 and 6, respectively. }) Contrasting tt(receive(int &value)) with tt(receive(int &&value)) has nothing to do with tt(int &value) not being a const reference. If tt(receive(int const &value)) is used the same results are obtained. Bottom line: the compiler selects the overloaded function using the rvalue reference if the function is passed an anonymous value. The compiler runs into problems if tt(void receive(int &value)) is replaced by tt(void receive(int value)), though. When confronted with the choice between a value parameter and a reference parameter (either lvalue or rvalue) it cannot make a decision and reports an ambiguity. In practical contexts this is not a problem. Rvalue references were added to the language in order to be able to distinguish the two forms of references: named values (for which lvalue references are used) and anonymous values (for which rvalue references are used). It is this distinction that allows the implementation of emi(move semantics) and emi(perfect forwarding). At this point the concept of emi(move semantics) cannot yet fully be discussed (but see section ref(MOVE) for a more thorough discussion) but it is very well possible to illustrate the underlying ideas. Consider the situation where a function returns a tt(struct Data) containing a pointer to a dynamically allocated NTBS. We agree that tt(Data) objects are only used after initialization, for which two tt(init) functions are available. As an aside: when tt(Data) objects are no longer required the memory pointed at by tt(text) must again be returned to the operating system; assume that that task is properly performed. verb( struct Data { char *text; void init(char const *txt); // initialize text from txt void init(Data const &other) { text = strdup(other.text); } };) There's also this interesting function: verb( Data dataFactory(char const *text);) Its implementation is irrelevant, but it returns a (temporary) tt(Data) object initialized with tt(text). Such temporary objects cease to exist once the statement in which they are created end. Now we'll use tt(Data): verb( int main() { Data d1; d1.init(dataFactory("object")); }) Here the tt(init) function duplicates the NTBS stored in the temporary object. Immediately thereafter the temporary object ceases to exist. If you think about it, then you realize that that's a bit over the top: itemization( it() the tt(dataFactory) function uses tt(init) to initialize the tt(text) variable of its temporary tt(Data) object. For that it uses tt(strdup); it() the tt(d1.init) function then em(also) uses tt(strdup) to initialize tt(d1.text); it() the statement ends, and the temporary object ceases to exist. ) That's two tt(strdup) calls, but the temporary tt(Data) object thereafter is never used again. To handle cases like these em(rvalue reference) were introduced. We add the following function to the tt(struct Data): verb( void init(Data &&tmp) { text = tmp.text; // (1) tmp.text = 0; // (2) }) Now, when the compiler translates tt(d1.init(dataFactory("object"))) it notices that tt(dataFactory) returns a (temporary) object, and because of that it uses the tt(init(Data &&tmp)) function. As we know that the tt(tmp) object ceases to exist after executing the statement in which it is used, the tt(d1) object (at (1)) em(grabs) the temporary object's tt(text) value, and then (at (2)) assigns 0 to tt(other.text) so that the temporary object's tt(free(text)) action does no harm. Thus, tt(struct Data) suddenly has become emi(move-aware) and implements em(move semantics), removing the (extra copy) drawback of the previous approach, and instead of making an extra copy of the temporary object's NTBS the pointer value is simply transferred to its new owner. c++-annotations-12.5.0/yo/first/separators.yo0000644000175000017500000000077514466730207020022 0ustar frankfrankTo improve the readability of large numbers em(digit separators)hi(digit separator) for integer and floating point literals can be used. The digit separator is a single quote which may be inserted between digits of such literals to enhance human readability. Multiple digit separators may be used, but only one separator can be inserted between successive digits. E.g., verb( 1'000'000 3.141'592'653'589'793'238'5 ''123 // won't compile 1''23 // won't compile either) c++-annotations-12.5.0/yo/first/structs.yo0000644000175000017500000000316514466730207017342 0ustar frankfrankEarlier we noted that functions can be part of tt(struct)s (see section ref(FunctionInStruct)). Such functions are called hi(member function)em(member functions). This section briefly discusses how to define such functions. The code fragment below shows a tt(struct) having data fields for a person's name and address. A function tt(print) is included in the tt(struct)'s definition: verb( struct Person { char name[80]; char address[80]; void print(); };) When defining the member function tt(print) the structure's name (tt(Person)) and the scope resolution operator (tt(::)) are used: verb( void Person::print() { cout << "Name: " << name << "\n" "Address: " << address << '\n'; }) The implementation of tt(Person::print) shows how the fields of the tt(struct) can be accessed without using the structure's type name. Here the function tt(Person::print) prints a variable tt(name). Since tt(Person::print) is itself a part of tt(struct) tt(person), the variable tt(name) implicitly refers to the same type. This tt(struct Person) could be used as follows: verb( Person person; strcpy(person.name, "Karel"); strcpy(person.address, "Marskramerstraat 33"); person.print();) The advantage of member functions is that the called function automatically accesses the data fields of the structure for which it was invoked. In the statement tt(person.print()) the object tt(person) is the `substrate': the variables tt(name) and tt(address) that are used in the code of tt(print) refer to the data stored in the tt(person) object. c++-annotations-12.5.0/yo/first/sharedcast.yo0000644000175000017500000000127314466730207017752 0ustar frankfrankThis section can safely be skipped without loss of continuity. In the context of the class tt(shared_ptr), which is covered in section ref(SHAREDPTR), several more new-style casts are available. Actual coverage of these specialized casts is postponed until section ref(SHAREDCAST). These specialized casts are: itemization( itt(static_pointer_cast), returning a tt(shared_ptr) to the base-class section of a derived class object; itt(const_pointer_cast), returning a tt(shared_ptr) to a non-const object from a tt(shared_ptr) to a constant object; itt(dynamic_pointer_cast), returning a tt(shared_ptr) to a derived class object from a tt(shared_ptr) to a base class object. ) c++-annotations-12.5.0/yo/first/scope.yo0000644000175000017500000000201114466730207016731 0ustar frankfrankbf(C++) introduces several new operators, among which the i(scope resolution operator) (ti(::)). This operator can be used in situations where a global variable exists having the same name as a local variable: verb( #include double counter = 50; // global variable int main() { for (int counter = 1; // this refers to the counter != 10; // local variable ++counter) { printf("%d\n", ::counter // global variable / // divided by counter); // local variable } }) In the above program the scope operator is used to address a global variable instead of the local variable having the same name. In bf(C++) the scope operator is used extensively, but it is seldom used to reach a global variable shadowed by an identically named local variable. Its main purpose is encountered in chapter ref(Classes). c++-annotations-12.5.0/yo/first/binary.yo0000644000175000017500000000115014466730207017107 0ustar frankfrankIn addition to hexadecimal hi(hexadecimal constant) integral constants (starting with i(0x)), octal integral hi(octal constant) constants (starting with i(0)), and decimal integral hi(decimal constant) constants (starting with one of the digits 1..9), em(binary) integral hi(binary constant) constants can be defined using the prefixes tt(0b)hi(0b, 0B) or tt(0B). E.g., to represent the (decimal) value 5 the notation tt(0b101) can also be used. The binary constants come in handy in the context of, e.g., i(bit-flags), as it immediately shows which bit-fields are set, while other notations are less informative. c++-annotations-12.5.0/yo/first/lvalues.yo0000644000175000017500000001016114466730207017300 0ustar frankfrankAlthough this section contains forward references to chapters ref(String), ref(Classes), and ref(PointMembers), its topic best fits the current chapter. This section can be skipped without loss of continuity, and you might consider returning to it once you're familiar with the content of these future chapters. Historically, the bf(C) programming language distinguished between em(lvalues) and em(rvalues). The terminology was based on assignment expressions, where the expression to the left of the assignment operator receives a value (e.g., it referred to a location in memory where a value could be written into, like a variable), while the expression to the right of the assignment operator only had to represent a value (it could be a temporary variable, a constant value or the value stored in a variable): verb( lvalue = rvalue;) bf(C++) adds to this basic distinction several new ways of referring to expressions: itemization( itt(lvalue): an emi(lvalue) in bf(C++) has the same meaning as in bf(C). It refers to a location where a value can be stored, like a variable, a reference to a variable, or a dereferenced pointer. itt(xvalue): an emi(xvalue) indicates an emi(expiring value). An expiring value refers to an em(object) (cf. chapter ref(Classes)) just before its lifetime ends. Such objects normally have to make sure that resources they own (like dynamically allocated memory) also cease to exist, but such resources may, just before the object's lifetime ends, be moved to another location, thus preventing their destruction. itt(glvalue): a emi(glvalue) is a emi(generalized lvalue). A generalized lvalue refers to anything that may receive a value. It is either an lvalue or an xvalue. itt(prvalue): a emi(prvalue) is a emi(pure rvalue): a literal value (like tt(1.2e3)) or an immutable object (e.g., the value returned from a function returning a constant tt(std::string) (cf. chapter ref(String))). ) An expression's value is an xvalue if it is: itemization( it() the value returned by a function returning an rvalue reference to an object; it() an object that is cast to an rvalue reference; it() an expression accessing a non-static class data member whose object is itemization( it() an xvalue, or it() a tt(.*) (pointer-to-member) expression (cf. chapter ref(PointMembers)) in which the left-hand side operand is an xvalue and the right-hand side operand is a pointer to a data member. ) The effect of this rule is that named rvalue references are treated as lvalues and anonymous rvalue references to objects are treated as xvalues.nl() Rvalue references to functions are treated as lvalues whether anonymous or not. ) Here is a small example. Consider this simple struct: verb( struct Demo { int d_value; };) In addition we have these function declarations and definitions: verb( Demo &&operator+(Demo const &lhs, Demo const &rhs); Demo &&factory(); Demo demo; Demo &&rref = static_cast(demo);) Expressions like verb( factory(); factory().d_value; static_cast(demo); demo + demo) are xvalues. However, the expression verb( rref;) is an lvalue. In many situations it's not particularly important to know what kind of lvalue or what kind of rvalue is actually used. In the annotations() the term emi(lhs) (i(left hand side)) is frequently used to indicate an operand that's written to the left of a binary operator, while the term emi(rhs) (i(right hand side)) is frequently used to indicate an operand that's written to the right of a binary operator. Lhs and rhs operands could actually be gvalues (e.g., when representing ordinary variables), but they could also be prvalues (e.g., numeric values added together using the addition operator). Whether or not lhs and rhs operands are gvalues or lvalues can always be determined from the context in which they are used. c++-annotations-12.5.0/yo/first/first.yo0000644000175000017500000000045714466730207016763 0ustar frankfrankIn this chapter bf(C++) is further explored. The possibility to declare functions in tt(struct)s is illustrated in various examples; the concept of a tt(class) is introduced; casting is covered in detail; many new types are introduced and several important notational extensions to bf(C) are discussed. c++-annotations-12.5.0/yo/first/designated.yo0000644000175000017500000000253514466730207017742 0ustar frankfrankbf(C++), like bf(C), also supports emi(designated initialization). However, as bf(C++) requires that destruction of data members occurs in the opposite order as their construction it is required that, when using designated initialization, members are initialized in the order in which they are declared in their class or struct. E.g., verb( struct Data { int d_first; double d_second; std::string d_third; }; Data data{ .d_first = 1, .d_third = "hello" };) In this example, tt(d_first) and tt(d_third) are explicitly initialized, while tt(d_second) is implicitly initialized to its default value (so: 0.0). In bf(C++) it is not allowed to reorder the initialization of members in a desginated initialization list. So, tt(Data data{ .d_third = "hello", .d_first = 1 }) is an error, but tt(Data data{ .d_third = "hello" }) is OK, as there is no ordering conflict in the latter example (this also initializes tt(d_first) and tt(d_second) to 0). Likewise, a union hi(union: designated initialization) can be initialized using designated initialization, as illustrated by the next example: verb( union Data { int d_first; double d_second; std::string *d_third; }; // initialize the union's d_third field: Data data{ .d_third = new string{ "hello" } };) c++-annotations-12.5.0/yo/first/dynamiccast.yo0000644000175000017500000000132714466730207020130 0ustar frankfrankFinally there is a new style cast that is used in combination with polymorphism (see chapter ref(POLYMORPHISM)). Its syntax is: verb( dynamic_cast(expression)) Different from the tt(static_cast), whose actions are completely determined em(compile-time), the tt(dynamic_cast)'s actions are determined em(run-time) to convert a pointer to an object of some class (e.g., tt(Base)) to a pointer to an object of another class (e.g., tt(Derived)) which is found further down its so-called em(class hierarchy) (this is also called em(downcasting)). At this point in the em(Annotations) a tt(dynamic_cast) cannot yet be discussed extensively, but we return to this topic in section ref(DYNAMICCAST). c++-annotations-12.5.0/yo/first/cast.yo0000644000175000017500000000154514466730207016565 0ustar frankfrankTraditionally, bf(C) offers the following em(cast) syntax: verb( (typename)expression) here tt(typename) is the name of a valid em(type), and tt(expression) is an expression. bf(C) style casts are now deprecated. bf(C++) programs should merely use the new style bf(C++) casts as they offer the compiler facilities to verify the sensibility of the cast. Facilities which are not offered by the classic bf(C)-style cast. A cast should not be confused with the often used emi(constructor notation): verb( typename(expression)) the constructor notation is not a cast, but a request to the compiler to construct an (anonymous) variable of type tt(typename) from tt(expression). If casts are really necessary one of several emi(new-style casts) should be used. These new-style casts are introduced in the upcoming sections. c++-annotations-12.5.0/yo/first/references.yo0000644000175000017500000002043414466730207017752 0ustar frankfrankIn addition to the common ways to define variables (plain variables or pointers) bf(C++) introduces hi(reference)em(references) defining synonyms for variables. A reference to a variable is like an em(alias); the variable and the reference can both be used in statements involving the variable: verb( int int_value; int &ref = int_value;) In the above example a variable tt(int_value) is defined. Subsequently a reference tt(ref) is defined, which (due to its initialization) refers to the same memory location as tt(int_value). In the definition of tt(ref), the i(reference operator) hi(operator&) tt(&) indicates that tt(ref) is not itself an tt(int) but a reference to one. The two statements verb( ++int_value; ++ref;) have the same effect: they increment tt(int_value)'s value. Whether that location is called tt(int_value) or tt(ref) does not matter. References serve an important function in bf(C++) as a means to pass modifiable arguments to functions. E.g., in standard bf(C), a function that increases the value of its argument by five and returning nothing needs a pointer parameter: verb( void increase(int *valp) // expects a pointer { // to an int *valp += 5; } int main() { int x; increase(&x); // pass x's address }) This construction can em(also) be used in bf(C++) but the same effect is also achieved using a reference: verb( void increase(int &valr) // expects a reference { // to an int valr += 5; } int main() { int x; increase(x); // passed as reference }) It is arguable whether code such as the above should be preferred over bf(C)'s method, though. The statement tt(increase) tt((x)) suggests that not tt(x) itself but a em(copy) is passed. Yet the value of tt(x) changes because of the way tt(increase()) is defined. However, references can also be used to pass objects that are only inspected (without the need for a copy or a const *) or to pass objects whose modification is an accepted side-effect of their use. In those cases using references are strongly preferred over existing alternatives like copy by value or passing pointers. Behind the scenes references are implemented using pointers. So, as far as the compiler is concerned references in bf(C++) are just const pointers. With references, however, the programmer does not need to know or to bother about levels of indirection. An important distinction between plain pointers and references is of course that with references no indirection takes place. For example: verb( extern int *ip; extern int &ir; ip = 0; // reassigns ip, now a 0-pointer ir = 0; // ir unchanged, the int variable it refers to // is now 0.) In order to prevent confusion, we suggest to adhere to the following: itemization( it() In those situations where a function does not alter its parameters of a built-in or pointer type, value parameters can be used: verb(void some_func(int val) { cout << val << '\n'; } int main() { int x; some_func(x); // a copy is passed }) it() When a function explicitly must change the values of its arguments, a pointer parameter is preferred. These pointer parameters should preferably be the function's initial parameters. This is called emi(return by argument). verb(void by_pointer(int *valp) { *valp += 5; }) it() When a function doesn't change the value of its class- or struct-type arguments, or if the modification of the argument is a trivial side-effect (e.g., the argument is a stream) references can be used. Const-references should be used if the function does not modify the argument: verb(void by_reference(string const &str) { cout << str; // no modification of str } int main () { int x = 7; by_pointer(&x); // a pointer is passed // x might be changed string str("hello"); by_reference(str); // str is not altered }) References play an important role in cases where the argument is not changed by the function but where it is undesirable to copy the argument to initialize the parameter. Such a situation occurs when a large object is passed as argument, or is returned by the function. In these cases the copying operation tends to become a significant factor, as the entire object must be copied. In these cases references are preferred. If the argument isn't modified by the function, or if the caller shouldn't modify the returned information, the tt(const) keyword should be used. Consider the following example: verb(struct Person // some large structure { char name[80]; char address[90]; double salary; }; Person person[50]; // database of persons // printperson expects a // reference to a structure // but won't change it void printperson (Person const &subject) { cout << "Name: " << subject.name << '\n' << "Address: " << subject.address << '\n'; } // get a person by index value Person const &personIdx(int index) { return person[index]; // a reference is returned, } // not a copy of person[index] int main() { Person boss; printperson(boss); // no pointer is passed, // so `boss' won't be // altered by the function printperson(personIdx(5)); // references, not copies // are passed here }) it() Furthermore, note that there is yet another reason for using references when passing objects as function arguments. When passing a reference to an object, the activation of a so called em(copy constructor) is avoided. Copy constructors are covered in chapter ref(MEMORY). ) References em(could) result in extremely `ugly' code. A function may return a reference to a variable, as in the following example: verb( int &func() { static int value; return value; }) This allows the use of the following constructions: verb( func() = 20; func() += func();) It is probably superfluous to note that such constructions should normally not be used. Nonetheless, there are situations where it is useful to return a reference. We have actually already seen an example of this phenomenon in our previous discussion of streams. In a statement like tt(cout) lshift() tt("Hello") lshift() tt('\n';) the insertion operator returns a reference to tt(cout). So, in this statement first the tt("Hello") is inserted into tt(cout), producing a reference to tt(cout). Through this reference the tt('\n') is then inserted in the tt(cout) object, again producing a reference to tt(cout), which is then ignored. Several differences between pointers and references are pointed out in the next list below: itemization( it() A reference cannot exist by itself, i.e., without something to refer to. A declaration of a reference like center(tt(int &ref;)) is not allowed; what would tt(ref) refer to? it() References can be declared as tt(external). These references were initialized elsewhere. it() References may exist as parameters of functions: they are initialized when the function is called. it() References may be used in the return types of functions. In those cases the function determines what the return value refers to. it() References may be used as data members of classes. We return to this usage later. it() Pointers are variables by themselves. They point at something concrete or just ``at nothing''. it() References are aliases for other variables and cannot be re-aliased to another variable. Once a reference is defined, it refers to its particular variable. it() Pointers (except for const pointers) can be reassigned to point to different variables. it() When an i(address-of operator) hi(operator&) ti(&) is used with a reference, the expression yields the address of the variable to which the reference applies. In contrast, ordinary pointers are variables themselves, so the address of a pointer variable has nothing to do with the address of the variable pointed to. ) c++-annotations-12.5.0/yo/first/auto.yo0000644000175000017500000001350714466730207016604 0ustar frankfrankThe keyword ti(auto) can be used to simplify type definitions of variables and return types of functions if the compiler is able to determine the proper types of such variables or functions. Using tt(auto) as a storage class specifier is no longer supported by bf(C++): a variable definition like tt(auto int var) results in a compilation error. The keyword tt(auto) is used in situations where it is very hard to determine the variable's type. These situations are encountered, e.g., in the context of em(templates) (cf. chapters ref(STL) until ref(ADVANCEDTEMPL)). It is also used in situations where a known type is a very long one but also automatically available to the compiler. In such cases the programmer uses tt(auto) to avoid having to type long type definitions. At this point in the Annotations only simple examples can be given. Refer to section ref(AUTODECL) for additional information about tt(auto) (and the related tt(decltype) function). When defining and initializing a variable tt(int variable = 5) the type of the initializing expression is well known: it's an tt(int), and unless the programmer's intentions are different this could be used to define tt(variable)'s type (a somewhat contrived example as in this case it reduces rather than improves the clarity of the code): verb( auto variable = 5;) However, it is attractive to use tt(auto). In chapter ref(String) the emi(iterator) concept is introduced (see also chapters ref(CONTAINERS) and ref(STL)). Iterators frequently have long type definitions, like verb( std::vector::const_reverse_iterator) Functions may return objects having such types. Since the compiler knows about these types we may exploit this knowledge by using tt(auto). Assume that a function tt(begin()) is declared like this: verb( std::vector::const_reverse_iterator begin();) Rather than writing a long variable definition (at tt(// 1), below) a much shorter definition (at tt(// 2)) can be used: verb( std::vector::const_reverse_iterator iter = begin(); // 1 auto iter = begin(); // 2) It's also easy to define and initialize additional variables of such types. When initializing such variables tt(iter) can be used to initialize those variables, and tt(auto) can be used, so the compiler deduces their types: verb( auto start = iter;) When defining variables using tt(auto) the variable's type is deduced from the variable's initializing expression. Plain types and pointer types are used as-is, but when the initializing expression is a reference type, then the reference's basic type (without the reference, omitting tt(const) or tt(volatile) specifications) is used. If a reference type is required then tt(auto &)hi(auto &, auto &&) or tt(auto &&) can be used. Likewise, tt(const) and/or pointer specifications can be used in combination with the tt(auto) keyword itself. Here are some examples: verb( int value; auto another = value; // 'int another' is defined string const &text(); auto str = text(); // text's plain type is string, so // string str, NOT string const str // is defined str += "..."; // so, this is OK int *ip = &value; auto ip2 = ip; // int *ip2 is defined. int *const &ptr = ip; auto ip3 = ptr; // int *ip3 is defined, omitting const & auto const &ip4 = ptr; // int *const &ip4 is defined.) In the next to last tt(auto) specification, the tokens (reading right to left) from the reference to the basic type are omitted: here tt(const &) was appended to tt(ptr's) basic type (tt(int *)). Hence, tt(int *ip2) is defined. In the last tt(auto) specification tt(auto) also produces tt(int *), but in the type definition tt(const &) is added to the type produced by tt(auto), so tt(int *const &ip4) is defined. The tt(auto) keyword can also be used to postpone the definition of a function's return type. The declaration of a function tt(intArrPtr) returning a pointer to arrays of 10 tt(int)s looks like this: verb( int (*intArrPtr())[10];) Such a declaration is fairly complex. E.g., among other complexities it requires `protection of the pointer'hi(pointer protection) using parentheses in combination with the function's parameter list. In situations like these the specification of the return type can be postponed using the tt(auto) return type, followed by the specification of the function's return type after any other specification the function might receive (e.g., as a const member (cf. section ref(ConstFunctions)) or following its tt(noexcept) specification (cf. section ref(NOEXCEPT))). Using tt(auto) to declare the above function, the declaration becomes: verb( auto intArrPtr() -> int (*)[10];) A return type specification using tt(auto) is called a emi(late-specified return type). Since the C++14 standard late return type specifications are no longer required for functions returning tt(auto). Such functions can now simply be declared like this: verb( auto autoReturnFunction();) In this case some restrictions apply, both to the function definitions and the function declarations: itemization( it() If multiple return statements are used in function definitions they all must return values of identical types; it() Functions merely returning tt(auto) cannot be used before the compiler has seen their definitions. So they cannot be used after mere declarations; it() When functions returning tt(auto) are implemented as recursive function then at least one return statement must have been seen before the recursive call. E.g., verb( auto fibonacci(size_t n) { if (n <= 1) return n; return fibonacci(n - 1) + fibonacci(n - 2); }) ) c++-annotations-12.5.0/yo/first/cout.yo0000644000175000017500000001513614466730207016606 0ustar frankfrankAnalogous to bf(C), bf(C++) defines standard input- and output streams which are available when a program is executed. The streams are: itemization( it() ti(cout), analogous to ti(stdout), it() ti(cin), analogous to ti(stdin), it() ti(cerr), analogous to ti(stderr). ) Syntactically these streams are not used as functions: instead, data are written to streams or read from them using the operators lshift(), called the emi(insertion operator) and rshift(), called the emi(extraction operator). This is illustrated in the next example: verb( #include using namespace std; int main() { int ival; char sval[30]; cout << "Enter a number:\n"; cin >> ival; cout << "And now a string:\n"; cin >> sval; cout << "The number is: " << ival << "\n" "And the string is: " << sval << '\n'; }) This program reads a number and a string from the tt(cin) stream (usually the keyboard) and prints these data to tt(cout). With respect to streams, please note: itemization( it() The standard streams are declared in the header file ti(iostream). In the examples in the annotations() this header file is often not mentioned explicitly. Nonetheless, it em(must) be included (either directly or indirectly) when these streams are used. Comparable to the use of the tt(using namespace std;) clause, the reader is expected to tt(#include ) with all the examples in which the standard streams are used. it() The streams tt(cout), tt(cin) and tt(cerr) are variables of so-called emi(class)-types. Such variables are commonly called em(objects). Classes are discussed in detail in chapter ref(Classes) and are used extensively in bf(C++). it() The stream tt(cin) extracts data from a stream and copies the extracted information to variables (e.g., tt(ival) in the above example) using the extraction operator (two consecutive tt(>) characters: rshift()). Later in the Annotations we will describe how operators in bf(C++) can perform quite different actions than what they are defined to do by the language, as is the case here. Function overloading has already been mentioned. In bf(C++) em(operators) can also have multiple definitions, which is called em(operator overloading). it() The operators which manipulate tt(cin), tt(cout) and tt(cerr) (i.e., rshift() and lshift()) also manipulate variables of different types. In the above example tt(cout) lshift() tt(ival) results in the printing of an integer value, whereas tt(cout) lshift() tt("Enter a number") results in the printing of a string. The actions of the operators therefore depend on the types of supplied variables. it() The emi(extraction operator) (rshift()) performs a so called emi(type safe) assignment to a variable by `extracting' its value from a text stream. Normally, the extraction operator skips all emi(whitespace) hi(skipping leading blanks) characters preceding the values to be extracted. it() Special i(symbolic constants) are used for special situations. Normally a line is terminated by inserting tt("\n") or tt('\n'). But when inserting the ti(endl) symbol the line is terminated followed by the flushing of the stream's internal buffer. Thus, tt(endl) can usually be avoided in favor of tt('\n') resulting in somewhat more efficient code. ) The stream objects tt(cin), tt(cout) and tt(cerr) are not part of the bf(C++) grammar proper. The streams are part of the definitions in the header file tt(iostream). This is comparable to functions like tt(printf) that are not part of the bf(C) grammar, but were originally written by people who considered such functions important and collected them in a run-time library. A program may still use the old-style functions like tt(printf) and tt(scanf) rather than the new-style streams. The two styles can even be mixed. But streams offer several clear advantages and in many bf(C++) programs have completely replaced the old-style bf(C) functions. Some advantages of using streams are: itemization( it() Using insertion and extraction operators is emi(type-safe). The format strings which are used with tt(printf) and tt(scanf) can define wrong format specifiers for their arguments, for which the compiler sometimes can't warn. In contrast, argument checking with tt(cin), tt(cout) and tt(cerr) is performed by the compiler. Consequently it isn't possible to err by providing an tt(int) argument in places where, according to the format string, a string argument should appear. With streams there are no format strings. it() The functions tt(printf) and tt(scanf) (and other functions using format strings) in fact implement a em(mini-language) which is interpreted at run-time. In contrast, with streams the bf(C++) compiler knows exactly which in- or output action to perform given the arguments used. No mini-language here. it() In addition the possibilities of the insertion and extraction operators may be em(extended) allowing objects of classes that didn't exist when the streams were originally designed to be inserted into or extracted from streams. Mini languages as used with tt(printf) cannot be extended. it() The usage of the left-shift and right-shift operators in the context of the streams illustrates yet another capability of bf(C++): operator overloading allowing us to redefine the actions an operator performs in certain contexts. Coming from bf(C) operator overloading requires some getting used to, but after a short little while these overloaded operators feel rather comfortable. it() Streams are independent of the media they operate upon. This (at this point somewhat abstract) notion means that the same code can be used without em(any) modification at all to interface your code to em(any) kind of device. The code using streams can be used when the device is a file on disk; an Internet connection; a digital camera; a DVD device; a satellite link; and much more: you name it. Streams allow your code to be decoupled (independent) of the devices your code is supposed to operate on, which eases maintenance and allows reuse of the same code in new situations. ) The em(iostream library) has a lot more to offer than just tt(cin, cout) and tt(cerr). In chapter ref(IOStreams) em(iostreams) are covered in greater detail. Even though ti(printf) and friends can still be used in bf(C++) programs, streams have practically replaced the old-style bf(C) tt(I/O) functions like tt(printf). If you em(think) you still need to use tt(printf) and related functions, think again: in that case you've probably not yet completely grasped the possibilities of stream objects. c++-annotations-12.5.0/yo/first/byte.yo0000644000175000017500000000470514522250221016561 0ustar frankfrankhi(byte) Quite often 8-bit variables are required, usually to access memory locations. Traditionally the tt(char) type has been used for that, but tt(char) is a signed type and when inserting a tt(char) variable into a stream the character's representation instead of its value is used. Maybe more important is the inherent confusion when using tt(char) type variables when only using its (unsigned) value: a tt(char) documents to the reader that text is used instead of mere 8-bit values, as used by the smallest addressable memory locations. Different from the tt(char) type the tt(std::byte) type intends to merely represent an 8-bit value. In order to use tt(std::byte) the tthi(cstddef) header file must be included. The tt(byte) is defined as a strongly typed enum, simply embedding an tt(unsigned char): verb( enum class byte: unsigned char {};) As a tt(byte) is an enum without predefined enum values plain assignments can only be used between tt(byte) values. tt(Byte) variables can be initialized using curly braces around an existing tt(byte) or around fixed values of at most 8 bits (see #1 in the following example). If the specified value doesn't fit in 8 bits (#2) or if the specified value is neither a tt(byte) nor an tt(unsigned char) type variable (#3) the compiler reports an error. Assignments or assignment-like initializations using rvalues which are tt(bytes) initialized using parentheses with values not fitting in 8 bits are accepted (#4, #5). In these cases, the specified values are truncated to their lowest 8 bits. Here are the illustrations: verbinsert(-s4 //init examples/byte.cc) The tt(byte) type supports all bit-wise operations, but the right-hand operand of the bit-wise operator must also be a tt(byte). E.g., verb( value &= byte(0xf0);) tt(Byte) type values can also be ordered and compared for (in)equality. Unfortunately, no other operations are supported. E.g., tt(bytes) cannot be added and cannot be inserted into or extracted from streams, which somehow renders the tt(std::byte) less useful than ordinary types (like tt(unsigned int, uint16_t)). When needed such operations em(can) be supported using casts (covered in section ref(CPPCASTS)), but it's considered good practice to avoid casts whenever possible. However, bf(C++) allows us to define a byte-type that em(does) behave like an ordinary numeric type, including and extracting its values into and from streams. In section ref(BYTE) such a type is developed. c++-annotations-12.5.0/yo/first/attributes.yo0000644000175000017500000001277114466730207020024 0ustar frankfrankAttributes hi(attribute) are compiler directives that are inserted into source files to inform the compiler of some peculiarity of the code (variable or function) that follows the specified attribute. Attributes are used to inform the compiler about situations that are intentional, and thus prevent the compiler from issuing warnings. The following attributes are recognized: itemization( ithtq(carries_dependency)([[carries_dependency]]) (This attribute is currently not yet covered by the annotations(). At this point in the annotations() it can safely be ignored. COMMENT( tt([[carries_dependency]]) Indicates that dependency chain in release-consume std::memory_order propagates in and out of the function, which allows the compiler to skip unnecessary memory fence instructions. This attribute may appear in two situations: (1) it may apply to the parameter declarations of a function or lambda-expressions, in which case it indicates that initialization of the parameter carries dependency into lvalue-to-rvalue conversion of that object. (2) It may apply to the function declaration as a whole, in which case it indicates that the return value carries dependency to the evaluation of the function call expression. This attribute must appear on the first declaration of a function or one of its parameters in any translation unit. If it is not used on the first declaration of a function or one of its parameters in another translation unit, the program is ill-formed; no diagnostic required. See std::kill_dependency for example usage END) ) ithtq(deprecated)([[deprecated]]) (This attribute (and its alternative form tt([[deprecated("reason")]])) is available since the C++14 standard. It indicates that the use of the name or entity declared with this attribute is allowed, but discouraged for some reason. This attribute can be used for classes, typedef-names, variables, non-static data members, functions, enumerations, and template specializations. An existing non-deprecated entity may be redeclared deprecated, but once an entity has been declared deprecated it cannot be redeclared as `undeprecated'. When encountering the tt([[deprecated]]) attribute the compiler generates a warning, e.g., verb( demo.cc:12:24: warning: 'void deprecatedFunction()' is deprecated [-Wdeprecated-declarations] deprecatedFunction(); demo.cc:5:21: note: declared here [[deprecated]] void deprecatedFunction()) When using the alternative form (e.g., tt([[deprecated("do not use")]] void fun())) the compiler generates a warning showing the text between the double quotes, e.g., verb( demo.cc:12:24: warning: 'void deprecatedFunction()' is deprecated: do not use [-Wdeprecated-declarations] deprecatedFunction(); demo.cc:5:38: note: declared here [[deprecated("do not use")]] void deprecatedFunction()) ) itt([[fallthrough]])hi(fallthrough)nl() When statements nested under tt(case) entries in tt(switch) statements continue into subsequent tt(case) or tt(default) entries the compiler issues a `falling through' warning. If falling through is intentional the attribute tt([[fallthrough]]), which then must be followed by a semicolon, should be used. Here is an annotated example: verb(void function(int selector) { switch (selector) { case 1: case 2: // no falling through, but merged entry points cout << "cases 1 and 2\n"; [[fallthrough]]; // no warning: intentionally falling through case 3: cout << "case 3\n"; case 4: // a warning is issued: falling through not // announced. cout << "case 4\n"; [[fallthrough]]; // error: there's nothing beyond } }) itt([[maybe_unused]])hi(maybe_unused)nl() This attribute can be applied to a class, typedef-name, variable, parameter, non-static data member, a function, an enumeration or an enumerator. When it is applied to an entity no warning is generated when the entity is not used. Example: verb(void fun([[maybe_unused]] size_t argument) { // argument isn't used, but no warning // telling you so is issued }) itt([[nodiscard]])hi(nodiscard)nl() The attribute tt([[nodiscard]]) may be specified when declaring a function, class or enumeration. If a function is declared tt([[nodiscard]]) or if a function returns an entity previously declared using tt([[nodiscard]]) then the return value of such a function may only be ignored when explicitly cast to void. Otherwise, when the return value is not used a warning is issued. Example: verb(int [[nodiscard]] importantInt(); struct [[nodiscard]] ImportantStruct { ... }; ImportantStruct factory(); int main() { importantInt(); // warning issued factory(); // warning issued }) ithtq(noreturn)([[noreturn]]) (tt([[noreturn]]) indicates that the function does not return. tt([[noreturn]]'s) behavior is undefined if the function declared with this attribute actually returns. The following standard functions have this attribute: tt(std::_Exit, std::abort, std::exit, std::quick_exit, std::unexpected, std::terminate, std::rethrow_exception, std::throw_with_nested, std::nested_exception::rethrow_nested), Here is an example of a function declaration and definition using the tt([[noreturn]]) attribute: verb( [[noreturn]] void doesntReturn(); [[noreturn]] void doesntReturn() { exit(0); }) ) ) c++-annotations-12.5.0/yo/first/constcast.yo0000644000175000017500000000210314466730207017623 0ustar frankfrankThe tt(const) keyword has been given a special place in casting. Normally anything tt(const) is tt(const) for a good reason. Nonetheless situations may be encountered where the tt(const) can be ignored. For these special situations the tt(const_cast) should be used. Its syntax is: verb( const_cast(expression)) A ti(const_cast(expression)) expression is used to undo the tt(const) attribute of a (pointer) type. The need for a tt(const_cast) may occur in combination with functions from the standard bf(C) library which traditionally weren't always as const-aware as they should. A function tt(strfun(char *s)) might be available, performing some operation on its tt(char *s) parameter without actually modifying the characters pointed to by tt(s). Passing tt(char const hello[] = "hello";) to tt(strfun) produces the warning verb( passing `const char *' as argument 1 of `fun(char *)' discards const) A tt(const_cast) is the appropriate way to prevent the warning: verb( strfun(const_cast(hello));) c++-annotations-12.5.0/yo/first/const.yo0000644000175000017500000001561314502557620016757 0ustar frankfrankEven though the keyword ti(const) is part of the bf(C) grammar, its use is more important and much more common and strictly used in bf(C++) than it is in bf(C). The tt(const) keyword is a modifier stating that the value of a variable or of an argument may not be modified. In the following example the intent is to change the value of a variable tt(ival), which fails: verb( int main() { int const ival = 3; // a constant int // initialized to 3 ival = 4; // assignment produces // an error message }) This example shows how tt(ival) may be initialized to a given value in its definition; attempts to change the value later (in an assignment) are not permitted. Variables that are declared tt(const) can, in contrast to bf(C), be used to specify the size of an array, as in the following example: verb( int const size = 20; char buf[size]; // 20 chars big) Another use of the keyword tt(const) is seen in the declaration of pointers, e.g., in pointer-arguments. In the declaration verb( char const *buf;) tt(buf) is a pointer variable pointing to tt(char)s. Whatever is pointed to by tt(buf) may not be changed through tt(buf): the tt(char)s are declared as tt(const). The pointer tt(buf) itself however may be changed. A statement like tt(*buf = 'a';) is therefore not allowed, while tt(++buf) is. In the declaration verb( char *const buf;) tt(buf) itself is a tt(const) pointer which may not be changed. Whatever tt(char)s are pointed to by tt(buf) may be changed at will. Finally, the declaration verb( char const *const buf;) is also possible; here, neither the pointer nor what it points to may be changed. The i(rule of thumb) for the placement of the keyword tt(const) is the following: what's written to the em(left) of tt(const) may not be changed. Although simple, this rule of thumb is, unfortunately, not often used. For example, hi(Stroustrup) Bjarne Stroustrup states (in hi(http://www.stroustrup.com/...) tlurl(https://www.stroustrup.com/bs_faq2.html#constplacement)): quote( em(Should I put "const" before or after the type?) em(I put it before, but that's a matter of taste. "const T" and "T const" were always (both) allowed and equivalent. For example:) verb( const int a = 1; // OK int const b = 2; // also OK) em(My guess is that using the first version will confuse fewer programmers (``is more idiomatic'').) ) But we've already seen an example where applying this simple `before' placement rule for the keyword tt(const) produces unexpected (i.e., unwanted) results as we will shortly see (below). Furthermore, the `idiomatic' before-placement also conflicts with the notion of emi(const functions), which we will encounter in section ref(ConstFunctions). With const functions the keyword tt(const) is also placed behind rather than before the name of the function. The definition or declaration (either or not containing tt(const)) should always be read from the variable or function identifier back to the type identifier: quote( ``Buf is a const pointer to const characters'' ) This rule of thumb is especially useful in cases where confusion may occur. In examples of bf(C++) code published in other places one often encounters the reverse: tt(const) em(preceding) what should not be altered. That this may result in sloppy code is indicated by our second example above: verb( char const *buf;) What must remain constant here? According to the sloppy interpretation, the pointer cannot be altered (as tt(const) precedes the pointer). In fact, the char values are the constant entities here, as becomes clear when we try to compile the following program: verb( int main() { char const *buf = "hello"; ++buf; // accepted by the compiler *buf = 'u'; // rejected by the compiler }) Compilation fails on the statement tt(*buf = 'u';) and em(not) on the statement tt(++buf). hi(Cline, M.) hi(http://www/parashift.com/c++-faq-lite/) i(Marshall Cline)'s turl(C++ FAQ) (http://www.parashift.com/c++-faq-lite/const-correctness.html) gives the same rule (paragraph 18.5) , in a similar context: quote(em( [18.5] What's the difference between "const Fred* p", "Fred* const p" and "const Fred* const p"?) em(You have to read pointer declarations right-to-left.) ) Marshall Cline's advice can be improved, though. Here's a recipe that will effortlessly dissect even the most complex declaration: enumeration( eit() start reading at the variable's name eit() read as far as possible until you reach the end of the declaration or an (as yet unmatched) closing parenthesis. eit() return to the point where you started reading, and read backwards until you reach the beginning of the declaration or a matching opening parenthesis. eit() If you reached an opening parenthesis, continue at step 2 beyond the parenthesis where you previously stopped. ) Let's apply this recipe to the following (by itself irrelevant) complex declaration. Little arrows indicate how far we should read at each step and the direction of the arrow indicates the reading direction: verb( char const *(* const (*(*ip)())[])[] ip Start at the variable's name: 'ip' is ip+CHAR(41) Hitting a closing paren: revert --> (*ip) Find the matching open paren: <- 'a pointer to' (*ip)()CHAR(41) The next unmatched closing par: --> 'a function (not expecting arguments)' (*(*ip)()) Find the matching open paren: <- 'returning a pointer to' (*(*ip)())[]CHAR(41) The next closing par: --> 'an array of' (* const (*(*ip)())[]) Find the matching open paren: <-------- 'const pointers to' (* const (*(*ip)())[])[] Read until the end: -> 'an array of' char const *(* const (*(*ip)())[])[] Read backwards what's left: <----------- 'pointers to const chars') Collecting all the parts, we get for tt(char const *(* const (*(*ip)())[])[]): em(ip is a pointer to a function (not expecting arguments), returning a pointer to an array of const pointers to an array of pointers to const chars). This is what tt(ip) represents; the recipe can be used to parse any declaration you ever encounter. c++-annotations-12.5.0/yo/string/0000755000175000017500000000000014522250262015423 5ustar frankfrankc++-annotations-12.5.0/yo/string/examples/0000755000175000017500000000000014624637126017254 5ustar frankfrankc++-annotations-12.5.0/yo/string/examples/stringreplace.cc0000664000175000017500000000213314624637133022424 0ustar frankfrank #include #include using namespace std; int main(int argc, char **argv) { if (argc != 3) { cerr << "Usage: to process " "stdin\n"; return 1; } string search(argv[1]); string replace(argv[2]); if (search == replace) { cerr << "The replace and search texts should be different\n"; return 1; } string line; while (getline(cin, line)) { string::size_type idx = 0; while (true) { idx = line.find(search, idx); // find(): another string member // see `searching' below if (idx == string::npos) break; line.replace(idx, search.size(), replace); idx += replace.length(); // don't change the replacement } cout << line << '\n'; } } c++-annotations-12.5.0/yo/string/examples/stringempty.cc0000664000175000017500000000077714624637133022163 0ustar frankfrank #include #include using namespace std; int main() { string stringOne; cout << "The length of the stringOne string is " << stringOne.size() << " characters\n" "It is " << (stringOne.empty() ? "" : " not ") << "empty\n"; stringOne = ""; cout << "After assigning a \"\"-string to a string-object\n" "it is " << (stringOne.empty() ? "also" : " not") << " empty\n"; } c++-annotations-12.5.0/yo/string/examples/stringinsert.cc0000664000175000017500000000071614624637133022322 0ustar frankfrank #include #include using namespace std; int main() { string stringOne("Hell ok."); // Insert "o " at position 4 stringOne.insert(4, "o "); string world("The World of C++"); // insert "World" into stringOne stringOne.insert(6, world, 4, 5); cout << "Guess what ? It is: " << stringOne << '\n'; } c++-annotations-12.5.0/yo/string/examples/stringcompare.cc0000664000175000017500000000163214624637133022442 0ustar frankfrank #include #include using namespace std; int main() { string stringOne("Hello World"); string stringTwo; if (stringOne != stringTwo) stringTwo = stringOne; if (stringOne == stringTwo) stringTwo = "Something else"; if (stringOne.compare(stringTwo) > 0) cout << "stringOne after stringTwo in the alphabet\n"; else if (stringOne.compare(stringTwo) < 0) cout << "stringOne before stringTwo in the alphabet\n"; else cout << "The two strings are the same\n"; // Alternatively: if (stringOne > stringTwo) cout << "stringOne after stringTwo in the alphabet\n"; else if (stringOne < stringTwo) cout << "stringOne before stringTwo in the alphabet\n"; else cout << "The two strings are the same\n"; } c++-annotations-12.5.0/yo/string/examples/stringswap.cc0000664000175000017500000000063614624637133021771 0ustar frankfrank #include #include using namespace std; int main() { string stringOne("Hello"); string stringTwo("World"); cout << "Before: stringOne: " << stringOne << ", stringTwo: " << stringTwo << '\n'; stringOne.swap(stringTwo); cout << "After: stringOne: " << stringOne << ", stringTwo: " << stringTwo << '\n'; } c++-annotations-12.5.0/yo/string/examples/stringsubstr.cc0000664000175000017500000000043614624637133022337 0ustar frankfrank #include #include using namespace std; int main() { string stringOne("Hello World"); cout << stringOne.substr(0, 5) << '\n' << stringOne.substr(6) << '\n' << stringOne.substr() << '\n'; } c++-annotations-12.5.0/yo/string/examples/stringsize.cc0000664000175000017500000000037214624637133021766 0ustar frankfrank #include #include using namespace std; int main() { string stringOne("Hello World"); cout << "The length of the stringOne string is " << stringOne.size() << " characters\n"; } c++-annotations-12.5.0/yo/string/examples/stringdata.cc0000664000175000017500000000166414624637133021732 0ustar frankfrank #include #include using namespace std; int main() { string stringOne("Hello World 12345678901234567890 "), stringTwo(5, 'a'), stringThree(stringOne.rbegin(), stringOne.rend()); stringOne.resize(20, 'z'); cout << "World at: " << stringOne.find("World") << '\n'; cout << stringOne << '\n'; stringTwo.append("hello world", 3, 5); stringTwo.insert(1, "..."); cout << stringTwo << '\n'; cout << (stringOne.data() ? "not a 0 ptr." : "0 ptr.") << '\n'; cout << (stringTwo.data() ? "not a 0 ptr." : "0 ptr.") << '\n'; cout << stringOne.data() << '\n' << "'" << stringTwo.data() << "'" << '\n'; cout << stringOne.max_size() << ", " << stringOne.capacity() << '\n'; cout << stringTwo.max_size() << ", " << stringTwo.capacity() << '\n'; return (0); } c++-annotations-12.5.0/yo/string/examples/stringassign.cc0000664000175000017500000000043214624637133022275 0ustar frankfrank #include using namespace std; int main() { string stringOne("Hello World"); string stringTwo; stringTwo = stringOne; // assign stringOne to stringTwo stringTwo = "Hello world"; // assign a C-string to StringTwo } c++-annotations-12.5.0/yo/string/examples/stringcompare2.cc0000664000175000017500000000346514624637133022532 0ustar frankfrank #include #include using namespace std; int main() { string stringOne("Hello World"); // comparing from a certain offset in stringOne if (!stringOne.compare(1, stringOne.length() - 1, "ello World")) cout << "comparing 'Hello world' from index 1" " to 'ello World': ok\n"; // the number of characters to compare (2nd arg.) // may exceed the number of available characters: if (!stringOne.compare(1, string::npos, "ello World")) cout << "comparing 'Hello world' from index 1" " to 'ello World': ok\n"; // comparing from a certain offset in stringOne over a // certain number of characters with a second C-string // This fails, as 3 chars in stringOne starting at // index 6 are compared with "World" if (!stringOne.compare(6, 3, "World")) cout << "comparing 'Hello World' from index 6 over" " 3 positions to 'World and more': ok\n"; else cout << "Unequal (sub)strings\n"; // This one will report a match, as only 5 characters are // compared of the source and target strings if (!stringOne.compare(6, 5, "World and more", 0, 5)) cout << "comparing 'Hello World' from index 6 over" " 5 positions to 'World and more': ok\n"; else cout << "Unequal (sub)strings\n"; } /* Generated output: comparing 'Hello world' from index 1 to 'ello World': ok comparing 'Hello world' from index 1 to 'ello World': ok Unequal (sub)strings comparing 'Hello World' from index 6 over 5 positions to 'World and more': ok */ c++-annotations-12.5.0/yo/string/examples/stringerase.cc0000664000175000017500000000043614624637133022114 0ustar frankfrank #include #include using namespace std; int main() { string stringOne("Hello Cruel World"); stringOne.erase(5, 6); cout << stringOne << '\n'; stringOne.erase(); cout << "'" << stringOne << "'\n"; } c++-annotations-12.5.0/yo/string/examples/stringcstr.cc0000664000175000017500000000033714624637133021770 0ustar frankfrank #include #include using namespace std; int main() { string stringOne("Hello World"); char const *cString = stringOne.c_str(); cout << cString << '\n'; } c++-annotations-12.5.0/yo/string/examples/stringfindfirst.cc0000664000175000017500000000226514624637133023007 0ustar frankfrank #include #include using namespace std; int main() { string line; getline(cin, line); string::size_type pos; cout << "Line: " << line << '\n' << "Starting at the first vowel:\n" << "'" << ( (pos = line.find_first_of("aeiouAEIOU")) != string::npos ? line.substr(pos) : "*** not found ***" ) << "'\n" << "Starting at the last vowel:\n" << "'" << ( (pos = line.find_last_of("aeiouAEIOU")) != string::npos ? line.substr(pos) : "*** not found ***" ) << "'\n" << "Starting at the first non-digit:\n" << "'" << ( (pos = line.find_first_not_of("1234567890")) != string::npos ? line.substr(pos) : "*** not found ***" ) << "'\n"; } c++-annotations-12.5.0/yo/string/examples/stringappend.cc0000664000175000017500000000114414624637133022261 0ustar frankfrank #include #include using namespace std; int main() { string stringOne("Hello"); string stringTwo("World"); stringOne += " " + stringTwo; stringOne = "hello"; stringOne.append(" world"); // append 5 characters: stringOne.append(" ok. >This is not used<", 5); cout << stringOne << '\n'; string stringThree("Hello"); // append " world": stringThree.append(stringOne, 5, 6); cout << stringThree << '\n'; } c++-annotations-12.5.0/yo/string/examples/stringsubscript.cc0000664000175000017500000000117714624637133023036 0ustar frankfrank #include #include using namespace std; int main() { string stringOne("Hello World"); stringOne[6] = 'w'; // now "Hello world" if (stringOne[0] == 'H') stringOne[0] = 'h'; // now "hello world" // *stringOne = 'H'; // THIS WON'T COMPILE stringOne = "Hello World"; // Now using the at() // member function: stringOne.at(6) = stringOne.at(0); // now "Hello Horld" if (stringOne.at(0) == 'H') stringOne.at(0) = 'W'; // now "Wello Horld" } c++-annotations-12.5.0/yo/string/members.yo0000644000175000017500000005520714501056022017432 0ustar frankfrankThe tt(std::string) class offers many member function as well as additional non-member functions that should be considered part of the string class. All these functions are listed below in alphabetic order. The symbolic value tt(string::npos) is defined by the string class. It represents `index-not-found' when returned by member functions returning string offset positions. Example: when calling `tt(object.find('x'))' (see below) on a string object not containing the character tt('x'), tt(npos) is returned, as the requested position does not exist. The final 0-byte used in bf(C) strings to indicate the end of an NTBS is em(not) considered part of a bf(C++) string, and so the member function will return tt(npos), rather than tt(length()) when looking for 0 in a string object containing the characters of a bf(C) string. Here are the standard functions that operate on objects of the class string. When a parameter of tt(size_t) is mentioned it may be interpreted as a parameter of type tt(string::size_type), but without defining a default argument value. The type tt(size_type) should be read as tt(string::size_type). With tt(size_type) the default argument values mentioned in section ref(STRINGOVERVIEW) apply. All quoted functions are member functions of the class tt(std::string), except where indicated otherwise. itemization( ithtq(at)(char &at(size_t opos)) (a reference to the character at the indicated position is returned. When called with tt(string const) objects a tt(char const &) is returned. The member function performs range-checking, raising an exception (that by default aborts the program) if an invalid index is passed.) ithtq(append) (string &append(InputIterator begin, InputIterator end)) (the characters in the range defined by tt(begin) and tt(end) are appended to the current string object.) ittq(string &append(string const &argument, size_type apos, size_type an)) (tt(argument) (or a substring) is appended to the current string object.) ittq(string &append(char const *argument, size_type an)) (the first tt(an) characters of tt(argument) are appended to the string object.) ittq(string &append(size_type n, char ch)) (tt(n) characters tt(ch) are appended to the current string object.) ithtq(assign)(string &assign(string const &argument, size_type apos, size_type an)) (tt(argument) (or a substring) is assigned to the string object. If tt(argument) is of type tt(char const *) and one additional argument is provided the second argument is interpreted as a value initializing tt(an), using 0 to initialize tt(apos).) ittq(string &assign(size_type n, char ch)) (tt(n) characters tt(ch) are assigned to the current string object.) ithtq(back)(char &back()) (returns a reference to the last tt(char) stored inside the string object. The result is undefined for empty strings.) ithtq(begin)(string::iterator begin()) (an iterator referring to the first character of the current string object is returned. With tt(const) string objects a tt(const_iterator) is returned.) ithtq(capacity)(size_type capacity() const) (the number of characters that can currently be stored in the string object without needing to resize it is returned.) ithtq(cbegin)(string::const_iterator cbegin()) (a tt(const_iterator) referring to the first character of the current string object is returned.) ithtq(cend)(string::const_iterator cend()) (a tt(const_iterator) referring to the end of the current string object is returned.) ithtq(clear)(void clear()) (the string's content is erased.) ithtq(compare)(int compare(string const &argument) const) (the text stored in the current string object and the text stored in tt(argument) is compared using a lexicographical comparison using the ASCII character collating sequence. zero is returned if the two strings have identical content, a negative value is returned if the text in the current object should be ordered em(before) the text in tt(argument); a positive value is returned if the text in the current object should be ordered em(beyond) the text in tt(argument).) ittq(int compare(size_t opos, size_t on, string const &argument) const) (a substring of the text stored in the current string object is compared to the text stored in tt(argument). At most tt(on) characters starting at offset tt(opos) are compared to the text in tt(argument).) ittq(int compare(size_t opos, size_t on, string const &argument, size_type apos, size_type an)) (a substring of the text stored in the current string object is compared to a substring of the text stored in tt(argument). At most tt(on) characters of the current string object, starting at offset tt(opos), are compared to at most tt(an) characters of tt(argument), starting at offset tt(apos). In this case tt(argument) em(must) be a string object.) ittq(int compare(size_t opos, size_t on, char const *argument, size_t an)) (a substring of the text stored in the current string object is compared to a substring of the text stored in tt(argument). At most tt(on) characters of the current string object starting at offset tt(opos) are compared to at most tt(an) characters of tt(argument). tt(Argument) must have at least tt(an) characters. The characters may have arbitrary values: 0-valued characters have no special meanings.) ithtq(contains)(bool contains(argument) const) (returns tt(true) if the object contains tt(argument's) characters as a substring. The argument can be a tt(string), a tt(string_view) (see section ref(STRINGVIEW)), a tt(char) or an NTBS.) ithtq(copy)(size_t copy(char *argument, size_t on, size_type opos) const) (the content of the current string object are (partially) copied into tt(argument). The actual number of characters copied is returned. The second argument, specifying the number of characters to copy, from the current string object is required. No 0-valued character is appended to the copied string but can be appended to the copied text using an idiom like the following: verb( argument[object.copy(argument, string::npos)] = 0;) Of course, the programmer should make sure that tt(argument)'s size is large enough to accommodate the additional 0-byte.) ithtq(crbegin)(string::const_reverse_iterator crbegin()) (a tt(const_reverse_iterator) referring to the last character of the current string object is returned.) ithtq(crend)(string::const_reverse_iterator crend()) (a tt(const_reverse_iterator) referring to the begin of the current string object is returned.) ithtq(c_str)(char const *c_str() const) (the content of the current string object as an NTBS.) ithtq(data)(char const *data() const) (the raw content of the current string object are returned. Since this member does not return an NTBS (as tt(c_str) does), it can be used to retrieve any kind of information stored inside the current string object including, e.g., series of 0-bytes: verb( string s(2, 0); cout << static_cast(s.data()[1]) << '\n';) ) ithtq(empty)(bool empty() const) (tt(true) is returned if the current string object contains no data.) ithtq(end)(string::iterator end()) (an iterator referring to the position just beyond the last character of the current string object is returned. With tt(const) string objects a tt(const_iterator) is returned.) ithtq(ends_with)(bool ends_with(argument) const) (returns tt(true) if the object's characters end with tt(argument). The argument can be a tt(string), a tt(string_view), a tt(char) or an NTBS.) ithtq(erase)(string &erase(size_type opos, size_type on)) (a (sub)string of the information stored in the current string object is erased.) ittq(string::iterator erase(string::iterator begin, string::iterator end)) (the parameter tt(end) is optional. If omitted the value returned by the current object's tt(end) member is used. The characters defined by the tt(begin) and tt(end) iterators are erased. The iterator tt(begin) is returned, which is then referring to the position immediately following the last erased character.) ithtq(find)(size_t find(string const &argument, size_type opos) const) (the first index in the current string object is returned where tt(argument) is found.) ittq(size_t find(char const *argument, size_type opos, size_type an) const) (the first index in the current string object is returned where tt(argument) is found. When all three arguments are specified the first argument em(must) be a tt(char const *).) ittq(size_t find(char ch, size_type opos) const) (the first index in the current string object is returned where tt(ch) is found.) ithtq(find_first_of)(size_t find_first_of(string const &argument, size_type opos) const) (the first index in the current string object is returned whose character matches any character from tt(argument).) ittq(size_type find_first_of(char const *argument, size_type opos, size_type an) const) (the first index in the current string object is returned whose character matches any character from tt(argument). If tt(opos) is provided it refers to the first index in the current string object where the search for tt(argument) should start. If omitted, the string object is completely scanned. If tt(an) is provided it indicates the number of characters of the tt(char const *) argument that should be used in the search. It defines a substring starting at the beginning of tt(argument). If omitted, all of tt(argument)'s characters are used.) ittq(size_type find_first_of(char ch, size_type opos)) (the first index in the current string object is returned whose character is equal to tt(ch).) ithtq(find_first_not_of)(size_t find_first_not_of(string const &argument, size_type opos) const) (the first index in the current string object is returned whose character does not match any character from tt(argument).) ittq(size_type find_first_not_of(char const *argument, size_type opos, size_type an) const) (the first index in the current string object is returned whose character does not match any character from tt(argument). The tt(opos) and tt(an) parameters are handled as with tt(find_first_of)) ittq(size_t find_first_not_of(char ch, size_type opos) const) (the first index in the current string object is returned whose character is unequal to tt(ch).) ithtq(find_last_of)(size_t find_last_of(string const &argument, size_type opos) const) (the last index in the current string object is returned whose character matches any character from tt(argument).) ittq(size_type find_last_of(char const *argument, size_type opos, size_type an) const) (the last index in the current string object is returned whose character matches any character from tt(argument). If tt(opos) is provided it refers to the last index in the current string object where the search for tt(argument) should start (searching backward towards the beginning of the current object). If omitted, the string object is scanned completely. If tt(an) is provided it indicates the number of characters of the tt(char const *) argument that should be used in the search. It defines a substring starting at the beginning of tt(argument). If omitted, all of tt(argument)'s characters are used.) ittq(size_type find_last_of(char ch, size_type opos)) (the last index in the current string object is returned whose character is equal to tt(ch).) ithtq(find_last_not_of)(size_t find_last_not_of(string const &argument, size_type opos) const) (the last index in the current string object is returned whose character does not match any character from tt(argument).) ittq(size_type find_last_not_of(char const *argument, size_type opos, size_type an) const) (the last index in the current string object is returned whose character does not match any character from tt(argument). The tt(opos) and tt(an) parameters are handled as with tt(find_last_of).) ittq(size_t find_last_not_of(char ch, size_type opos) const) (the last index in the current string object is returned whose character is unequal to tt(ch).) ithtq(front)(char &front()) (returns a reference to the first tt(char) stored inside the string object. The result is undefined for empty strings.) ithtq(get_allocator)(allocator_type get_allocator()) (returns the allocator of the class tt(std::string)) ithtq(getline)(istream &std::getline(istream &istr, string &object, char delimiter = '\n')) (Note: this is em(not) a member function of the class tt(string).nl() A line of text is read from tt(istr). All characters until tt(delimiter) (or the end of the stream, whichever comes first) are read from tt(istr) and are stored in tt(object). If the delimiter is encountered it is removed from the stream, but is not stored in tt(object).nl() If the delimiter is not found, tt(istr.eof) returns tt(true) (see section ref(IOSTATES)). Since streams may be interpreted as tt(bool) values (cf. section ref(IOSTATES)) a commonly encountered idiom to read all lines from a stream successively into a string object tt(line) looks like this: verb( while (getline(istr, line)) process(line);) The content of the last line, whether or not it was terminated by a delimiter, is eventually also assigned to tt(object).) ithtq(insert)(string &insert(size_t opos, string const &argument, size_type apos, size_type an)) (a (sub)string of tt(argument) is inserted into the current string object at the current string object's index position tt(opos). Arguments for tt(apos) and tt(an) must either both be provided or they must both be omitted.) ittq(string &insert(size_t opos, char const *argument, size_type an)) (tt(argument) (of type tt(char const *)) is inserted at index tt(opos) into the current string object.) ittq(string &insert(size_t opos, size_t count, char ch)) (tt(Count) characters tt(ch) are inserted at index tt(opos) into the current string object.) ittq(string::iterator insert(string::iterator begin, char ch)) (the character tt(ch) is inserted at the current object's position referred to by tt(begin). tt(Begin) is returned.) ittq(string::iterator insert(string::iterator begin, size_t count, char ch)) (tt(Count) characters tt(ch) are inserted at the current object's position referred to by tt(begin). tt(Begin) is returned.) ittq(string::iterator insert(string::iterator begin, InputIterator abegin, InputIterator aend)) (the characters in the range defined by the tt(InputIterators abegin) and tt(aend) are inserted at the current object's position referred to by tt(begin). tt(Begin) is returned.) ithtq(length)(size_t length() const) (the number of characters stored in the current string object is returned.) ithtq(max_size)(size_t max_size() const) (the maximum number of characters that can be stored in the current string object is returned.) ithtq(pop_back)(void pop_back()) (The string's last character is removed from the string object.) ithtq(push_back)(void push_back(char ch)) (The character tt(ch) is appended to the string object.) ithtq(rbegin)(string::reverse_iterator rbegin()) (a reverse iterator referring to the last character of the current string object is returned. With tt(const) string objects a tt(const_reverse_iterator) is returned.) ithtq(rend)(string::reverse_iterator rend()) (a reverse iterator referring to the position just before the first character of the current string object is returned. With tt(const) string objects a tt(const_reverse_iterator) is returned.) ithtq(replace)(string &replace(size_t opos, size_t on, string const &argument, size_type apos, size_type an)) (a (sub)string of characters in tt(object) are replaced by the (subset of) characters of tt(argument). If tt(on) is specified as 0 tt(argument) is inserted into tt(object) at offset tt(opos).) ittq(string &replace(size_t opos, size_t on, char const *argument, size_type an)) (a series of characters in tt(object) are replaced by the first tt(an) characters of tt(char const *) argument.) ittq(string &replace(size_t opos, size_t on, size_type count, char ch)) (tt(on) characters of the current string object, starting at index position tt(opos), are replaced by tt(count) characters tt(ch).) ittq(string &replace(string::iterator begin, string::iterator end, string const &argument)) (the series of characters in the current string object defined by the iterators tt(begin) and tt(end) are replaced by tt(argument). If tt(argument) is a tt(char const *), an additional argument tt(an) may be used, specifying the number of characters of tt(argument) that are used in the replacement.) ittq(string &replace(string::iterator begin, string::iterator end, size_type count, char ch)) (the series of characters in the current string object defined by the iterators tt(begin) and tt(end) are replaced by tt(count) characters having values tt(ch).) ittq(string &replace(string::iterator begin, string::iterator end, InputIterator abegin, InputIterator aend)) (the series of characters in the current string object defined by the iterators tt(begin) and tt(end) are replaced by the characters in the range defined by the tt(InputIterators abegin) and tt(aend).) ithtq(reserve)(void reserve(size_t request)) (the current string object's capacity is changed to at least tt(request). After calling this member, tt(capacity)'s return value will be at least tt(request). A request for a smaller size than the value returned by tt(capacity) is ignored. A hi(length_error)tt(std::length_error) exception is thrown if tt(request) exceeds the value returned by tt(max_size) (tt(std::length_error) is defined in the ti(stdexcept) header). Calling tt(reserve()) has the effect of redefining a string's capacity: when enlarging the capacity extra memory is allocated, but not immediately available to the program. This is illustrated by the exception thrown by the string's tt(at()) member when trying to access an element exceeding the string's tt(size) but not the string's tt(capacity).) ithtq(resize)(void resize(size_t size, char ch = 0)) (the current string object is resized to tt(size) characters. If the string object is resized to a size larger than its current size the additional characters will be initialized to tt(ch). If it is reduced in size the characters having the highest indices are chopped off.) ithtq(rfind)(size_t rfind(string const &argument, size_type opos) const) (the last index in the current string object where tt(argument) is found is returned. Searching proceeds from the current object's offset tt(opos) back to its beginning.) ittq(size_t rfind(char const *argument, size_type opos, size_type an) const) (the last index in the current string object where tt(argument) is found is returned. Searching proceeds from the current object's offset tt(opos) back to its beginning. The parameter tt(an) specifies the length of the substring of tt(argument) to look for, starting at tt(argument)'s beginning.) ittq(size_t rfind(char ch, size_type opos)const) (the last index in the current string object where tt(ch) is found is returned. Searching proceeds from the current object's offset tt(opos) back to its beginning.) ithtq(shrink_to_fit)(void shrink_to_fit()) (optionally reduces the amount of memory allocated by a vector to its current size. The implementor is free to ignore or otherwise optimize this request. In order to guarantee a `shrink to fit' operation the verb( string{ stringObject }.swap(stringObject)) idiom can be used.) ithtq(size)(size_t size() const) (the number of characters stored in the current string object is returned. This member is a synonym of tt(length()).) ithtq(starts_with)(bool starts_with(argument) const) (returns tt(true) if the object's character range starts with tt(argument). The argument can be a tt(string), a tt(string_view), a tt(char) or an NTBS.) ithtq(substr)(string substr(size_type opos, size_type on) const) (a substring of the current string object of at most tt(on) characters starting at index tt(opos) is returned.) ithtq(swap)(void swap(string &argument)) (the content of the current string object are swapped with the content of tt(argument). For this member tt(argument) must be a string object and cannot be a tt(char const *).) ) COMMENT( verbinclude(-a examples/stringassign.cc) verbinclude(-a examples/stringcstr.cc) verbinclude(-a examples/stringsubscript.cc) verbinclude(-a examples/stringcompare.cc) verbinclude(-a examples/stringcompare2.cc) verbinclude(-a examples/stringappend.cc) verbinclude(-a examples/stringinsert.cc) verbinclude(-a examples/stringreplace.cc) verbinclude(-a examples/stringswap.cc) verbinclude(-a examples/stringerase.cc) verbinclude(-a examples/stringsubstr.cc) verbinclude(-a examples/stringfindfirst.cc) verbinclude(-a examples/stringsize.cc) verbinclude(-a examples/stringempty.cc) END COMMENT) c++-annotations-12.5.0/yo/string/convertors.yo0000644000175000017500000001244114466730207020213 0ustar frankfrankSeveral string conversion functions are available operating on or producing tt(std::string) objects. These functions are listed below in alphabetic order. They are not member functions, but class-less (free) functions declared in the tt(std) namespace. The tthi(string) header file must be included before they can be used. itemization( ithtq(stof)(float stof(std::string const &str, size_t *pos = 0)) (Initial whitespace characters in tt(str) are ignored. Then the following sequences of characters are converted to a tt(float) value, which is returned: itemization( it() A decimal floating point constant: itemization( it() An optional + or - character it() A series of decimal digits, possibly containing one decimal point character it() An optional e or E character, followed by an optional - or + character, followed by a series of decimal digits ) it() A hexadecimal floating point constant: itemization( it() An optional + or - character it() 0x or 0X it() A series of hexadecimal digits, possibly containing one decimal point character it() An optional p or P character, followed by an optional - or + character, followed by a series of decimal digits ) it() An infinity expression: itemization( it() An optional + or - character it() The words tt(inf) or tt(infinity) (case insensitive words) ) it() A `not a number' expression: itemization( it() An optional + or - character it() The words tt(nan) or tt(nan(alphanumeric character sequence)) (tt(nan) is a case insensitive word), resulting in a tt(NaN) floating point value ) ) If tt(pos != 0) the index of the first character in tt(str) which was not converted is returned in tt(*pos). A tt(std::invalid_argument) exception is thrown if the characters in tt(str) could not be converted to a tt(float), a tt(std::out_of_range) exception is thrown if the converted value would have exceeded the range of tt(float) values.) ithtq(stod)(double stod(std::string const &str, size_t *pos = 0)) (A conversion as described with tt(stof) is performed, but now to a value of type tt(double).) ithtq(stold)(double stold(std::string const &str, size_t *pos = 0)) (A conversion as described with tt(stof) is performed, but now to a value of type tt(long double).) ithtq(stoi)(int stoi(std::string const &str, size_t *pos = 0, int base = 10)) (Initial whitespace characters in tt(str) are ignored. Then all characters representing numeric constants of the number system whose tt(base) is specified are converted to an tt(int) value, which is returned. An optional + or - character may prefix the numeric characters. Values starting with 0 are automatically interpreted as octal values, values starting with 0x or 0X as hexadecimal characters. The value tt(base) must be between 2 and 36. If tt(pos != 0) the index of the first character in tt(str) which was not converted is returned in tt(*pos). A tt(std::invalid_argument) exception is thrown if the characters in tt(str) could not be converted to an tt(int), a tt(std::out_of_range) exception is thrown if the converted value would have exceeded the range of tt(int) values. Here is an example of its use: verb(int value = stoi(" -123"s); // assigns value -123 value = stoi(" 123"s, 0, 5); // assigns value 38) ) ithtq(stol)(long stol(std::string const &str, size_t *pos = 0, int base = 10)) (A conversion as described with tt(stoi) is performed, but now to a value of type tt(long).) ithtq(stoll)(long long stoll(std::string const &str, size_t *pos = 0, int base = 10)) (A conversion as described with tt(stoi) is performed, but now to a value of type tt(long long).) ithtq(stoul)(unsigned long stoul(std::string const &str, size_t *pos = 0, int base = 10)) (A conversion as described with tt(stoi) is performed, but now to a value of type tt(unsigned long).) ithtq(stoull)(unsigned long long stoull(std::string const &str, size_t *pos = 0, int base = 10)) (A conversion as described with tt(stoul) is performed, but now to a value of type tt(unsigned long long).) ithtq(to_string)(std::string to_string(Type value)) (Type can be of the types tt(int, long, long long, unsigned, unsigned long, unsigned long long, float, double,) or tt(long double). The value of the argument is converted to a textual representation, which is returned as a tt(std::string) value. ) ithtq(to_wstring)(std::wstring to_wstring(Type value)) (The conversion as described at tt(to_string) is performed, returning a ti(std::wstring).) ) c++-annotations-12.5.0/yo/string/string.yo0000644000175000017500000000476014466730207017322 0ustar frankfrankbf(C++) offers many solutions for common problems. Most of these facilities are part of the em(Standard Template Library) or they are implemented as em(generic algorithms) (see chapter ref(GENERIC)). Among the facilities bf(C++) programmers have developed over and over again are those manipulating chunks of text, commonly called em(strings). The bf(C) programming language offers rudimentary string support. To process text bf(C++) offers a hi(string)tt(std::string) type. In bf(C++) the traditional bf(C) library functions manipulating NTB strings are deprecated in favor of using tt(string) objects. Many problems in bf(C) programs are caused by buffer overruns, boundary errors and allocation problems that can be traced back to improperly using these traditional bf(C) string library functions. Many of these problems can be prevented using bf(C++) string objects. Actually, tt(string) objects are em(class type) variables, and in that sense they are comparable to stream objects like tt(cin) and tt(cout). In this section the use of tt(string) type objects is covered. The focus is on their definition and their use. When using tt(string) objects the emi(member function) em(syntax) is commonly used: verb( stringVariable.operation(argumentList)) For example, if tt(string1) and tt(string2) are variables of type tt(std::string), then verb( string1.compare(string2)) can be used to compare both strings. In addition to the common member functions the tt(string) class also offers a wide variety of em(operators), like the assignment (tt(=)) and the comparison operator (tt(==)). Operators often result in code that is easy to understand and their use is generally preferred over the use of member functions offering comparable functionality. E.g., rather than writing verb( if (string1.compare(string2) == 0)) the following is generally preferred: verb( if (string1 == string2)) To define and use tt(string)-type objects, sources must include the header file tthi(string). To merely hi(string: declaring) em(declare) the string type the header i(iosfwd) can be included. In addition to tt(std::string), the header file tt(string) defines the following string types: itemization( itht(wstring)(std::wstring), a string type consisting of tt(wchar_t) characters; itht(u16string)(std::u16string), a string type consisting of tt(char16_t) characters; itht(u32string)(std::u32string), a string type consisting of tt(char32_t) characters. ) c++-annotations-12.5.0/yo/string/initializers.yo0000644000175000017500000000326614522250262020511 0ustar frankfrankAfter defining string objects they are guaranteed to be in a valid state. At em(definition time) string objects may be initialized in one of the following ways: The following tt(string) constructors hi(string constructors) are available: itemization( ittq(string object) (initializes tt(object) to an empty string. When defining a tt(string) this way no argument list may be specified;) ittq(string object(string::size_type count, char ch)) (initializes tt(object) with tt(count) characters tt(ch). em(Caveat:) to initialize a string object using this constructor do not use the curly braces variant, but use the constructor as shown, to avoid selecting the initializer-list constructor (see below);) ittq(string object(string const &argument)) (initializes tt(object) with tt(argument);) ittq(string object(std::string const &argument, string::size_type apos, string::size_type an)) (initializes tt(object) with tt(argument)'s content starting at index position tt(apos), using at most tt(an) of tt(argument)'s characters;) ittq(string object(InputIterator begin, InputIterator end)) (initializes tt(object) with the characters in the range of characters defined by the two tt(InputIterators).) ittq(string object(std::initializer_list chars)) (initializes tt(object) with the characters specified in the initializer list. The string may also directly be initialized, using the curly braced initialization. Here is an example showing both forms: verb(string str1({'h', 'e', 'l', 'l', 'o'}); string str2{ 'h', 'e', 'l', 'l', 'o' };) ) ) c++-annotations-12.5.0/yo/string/operators.yo0000644000175000017500000000607114466730207020027 0ustar frankfrankString objects may be manipulated by member functions but also by operators. Using operators often results in more natural-looking code. In cases where operators are available having equivalent functionality as member function the operator is practically always preferred. The following operators are available for tt(string) objects (in the examples `object' and `argument' refer to existing tt(std::string) objects). itemization( it() plain assignment: quote(a character, bf(C) or bf(C++) string may be assigned to a tt(string) object. The assignment operator returns its left-hand side operand. Example: verb(object = argument; object = "C string"; object = 'x'; object = 120; // same as object = 'x') ) it() addition: quote(the arithmetic additive assignment operator and the addition operator add text to a tt(string) object. The compound assignment operator returns its left-hand side operand, the addition operator returns its result in a temporary string object. When using the addition operator either the left-hand side operand or the right-hand side operand must be a tt(std::string) object. The other operand may be a char, a bf(C) string or a bf(C++) string. Example: verb(object += argument; object += "hello"; object += 'x'; // integral expressions are OK argument + otherArgument; // two std::string objects argument + "hello"; // using + at least one "hello" + argument; // std::string is required argument + 'a'; // integral expressions are OK 'a' + argument;) ) it() index operator: quote(The index operator may be used to retrieve tt(object)'s individual characters, or to assign new values to individual characters of a non-const string object. There is no range-checking (use the tt(at()) member function for that). This operator returns a tt(char &) or tt(char const &). Example: verb(object[3] = argument[5];) ) it() logical operators: quote(the logical comparison operators may be applied to two string objects or to a string object and a bf(C) string to compare their content. These operators return a tt(bool) value. The tt(==, !=, >, >=, <,) and tt(<=) operators are available. The ordering operators perform a lexicographical comparison of their content using the ASCII character collating sequence. Example: verb(object == object; // true object != (object + 'x'); // true object <= (object + 'x'); // true) ) it() stream related operators: quote(the insertion-operator (cf. section ref(CoutCinCerr)) may be used to insert a tt(string) object into an tt(ostream), the extraction-operator may be used to extract a string object from an tt(istream). The extraction operator by default first ignores all whitespace characters and then extracts all consecutively non-blank characters from an tt(istream). Instead of a string a character array may be extracted as well, but the advantage of using a string object should be clear: the destination string object is automatically resized to the required number of characters. Example: verb(cin >> object; cout << object;) ) ) c++-annotations-12.5.0/yo/string/iterators.yo0000644000175000017500000000246314501056030020007 0ustar frankfrank See section ref(ITERATORS) for details about em(iterators). As a quick introduction to iterators: an iterator acts like a pointer, and pointers can often be used in situations where iterators are requested. Iterators usually come in pairs, defining a range of entities. The begin-iterator points to the first entity, the end-iterator points just beyond the last entity of the range. Their difference is equal to the number of entities in the iterator-range. Iterators play an important role in the context of em(generic algorithms) (cf. chapter ref(GENERIC)). The class tt(std::string) defines the following hi(string: iterator types)em(iterator types): itemization( itt(string::iterator) and tt(string::const_iterator): quote(these iterators are emi(forward iterators). The tt(const_iterator) is returned by tt(string const) objects, the plain tt(iterator) is returned by non-const string objects. Characters referred to by tt(iterators) may be modified;) itt(string::reverse_iterator) and tt(string::const_reverse_iterator): quote(these iterators are also emi(forward iterators) but when em(incrementing) the iterator the em(previous) character in the string object is reached. Other than that they are comparable to, respectively, tt(string::iterator) and tt(string::const_iterator).) ) c++-annotations-12.5.0/yo/string/overview.yo0000644000175000017500000000643114466730207017657 0ustar frankfrankIn this section the string members and string-related operations are referenced. The subsections cover, respectively the string's initializers, iterators, operators, and member functions. The following terminology is used throughout this section: itemization( it() tt(object) is always a tt(string)-object; it() tt(argument) is a tt(string const &) or a tt(char const *) unless indicated otherwise. The content of an tt(argument) never is modified by the operation processing the tt(argument); it() tt(opos) refers to an offset into an tt(object) string; it() tt(apos) refers to an offset into an tt(argument); it() tt(on) represents a number of characters in an tt(object) (starting at tt(opos)); it() tt(an) represents a number of characters in an tt(argument) (starting at tt(apos)). ) Both tt(opos) and tt(apos) must refer to existing offsets, or an exception (cf. chapter ref(EXCEPTIONS)) is generated. In contrast, tt(an) and tt(on) may exceed the number of available characters, in which case only the available characters are considered. Many members declare default values for tt(on, an) and tt(apos). Some members declare default values for tt(opos). Default offset values are 0, the default values of tt(on) and tt(an) is tt(string::npos), which can be interpreted as `the required number of characters to reach the end of the string'. With members starting their operations at the end of the string object's content proceeding backwards, the default value of tt(opos) is the index of the object's em(last) character, with tt(on) by default equal to tt(opos + 1), representing the length of the substring em(ending) at tt(opos). In the overview of member functions presented below it may be assumed that all these parameters accept default values unless indicated otherwise. Of course, the default argument values cannot be used if a function requires additional arguments beyond the ones otherwise accepting default values. Some members have overloaded versions expecting an initial argument of type tt(char const *). But even if that is not the case the first argument can em(always) be of type tt(char const *) where a parameter of tt(std::string) is defined. Several member functions accept em(iterators). Section ref(ITERATORS) covers the technical aspects of em(iterators), but these may be ignored at this point without loss of continuity. Like tt(apos) and tt(opos), iterators must refer to existing positions and/or to an existing range of characters within the string object's content. All tt(string)-member functions computing indices return the predefined constant tt(string::npos) on failure. The ti(s) i(literal suffix) to indicate that a tt(std::string) constant is intended when a string literal (like tt("hello world")) is used. It can be used after declaring tt(using namespace std) or, more specific, after declaring hi(literals namespace)hi(string_literals namespace) tt(using namespace std::literals::string_literals). When string literals are used when explicitly defining or using tt(std::string) objects the tt(s)-suffix is hardly ever required, but it may come in handy when using the tt(auto) keyword. E.g., tt(auto str = "hello world"s) defines tt(std::string str), whereas it would have been a tt(char const *) if the literal suffix had been omitted. c++-annotations-12.5.0/yo/string/ops.yo0000644000175000017500000001126714466730207016615 0ustar frankfrankSome of the operations that can be performed on strings return indices within the strings. Whenever such an operation fails to find an appropriate index, the em(value) hi(npos)tt(string::npos) is returned. This value is a symbolic value of type hi(size_type)ti(string::size_type), which is (for all practical purposes) an (tt(unsigned)) tt(int). All tt(string) member functions accepting tt(string) objects as arguments also accept NTBS arguments. The same usually holds true for operators accepting tt(string) objects. Some tt(string)-members use em(iterators). Iterators are formally introduced in section ref(ITERATORS). Member functions using iterators are listed in the next section (ref(STRINGOVERVIEW)), but the iterator concept itself is not further covered by this chapter. Strings support a large variety of members and operators. A short overview listing their capabilities is provided in this section, with subsequent sections offering a detailed discussion. The bottom line: bf(C++) strings are extremely versatile and there is hardly a reason for falling back on the bf(C) library to process text. bf(C++) strings handle all the required memory management and thus memory related problems, which are the #1 source of problems in bf(C) programs, can be prevented when bf(C++) strings are used. Strings do come at a price, though. The class's extensive capabilities have also turned it into a beast. It's hard to learn and master all its features and in the end you'll find that not all that you expected is actually there. For example, tt(std::string) doesn't offer case-insensitive comparisons. But in the end it isn't even as simple as that. It em(is) there, but it is somewhat hidden and at this point in the annotations() it's too early to study into that hidden corner yet. Instead, realize that bf(C)'s standard library em(does) offer useful functions that can be used as long as we're aware of their limitations and are able to avoid their traps. So for now, to perform a traditional i(case-insensitive) comparison of the content of two tt(std::string) objects tt(str1) and tt(str2) the following will do: hi(strcasecmp) verb( strcasecmp(str1.c_str(), str2.c_str());) Strings support the following functionality: itemization( ittq(initialization) (when string objects are defined they are always properly initialized. In other words, they are always in a i(valid state). Strings may be initialized empty or already existing text can be used to initialize strings.) ittq(assignment) (strings may be given new values. New values may be assigned using member functions (like tt(assign)) but a plain assignment operator (i.e., tt(=))may also be used. Furthermore, assignment em(to) a character buffer is also supported.) ittq(conversions) (the partial or complete content of string objects may be interpreted as bf(C) strings but the string's content may also be processed as a series of raw binary bytes, not necessarily terminating in a 0-valued character. Furthermore, in many situations plain characters and bf(C) strings may be used where tt(std::string)s are accepted as well.) ittq(breakdown) (the individual characters stored in a string can be accessed using the familiar index operator (tt([])) allowing us to either access or modify information in the middle of a string.) ittq(comparisons) (strings may be compared to other strings (NTBSs) using the familiar logical comparison operators tt(==, !=, <, <=, >) and tt(>=). There are also member functions available offering a more fine-grained comparison.) ittq(modification) (the content of strings may be modified in many ways. Operators are available to add information to string objects, to insert information in the middle of string objects, or to replace or erase (parts of) a string's content.) ittq(swapping) (the string's swapping capability allows us in principle to exchange the content of two string objects without a byte-by-byte copying operation of the string's content.) ittq(searching) (the locations of characters, sets of characters, or series of characters may be searched for from any position within the string object and either searching in a forward or backward direction.) ittq(housekeeping) (several housekeeping facilities are offered: the string's length, or its empty-state may be interrogated. But string objects may also be resized.) ittq(stream I/O) (strings may be extracted from or inserted into streams. In addition to plain string extraction a line of a text file may be read without running the risk of a buffer overrun. Since extraction and insertion operations are stream based the I/O facilities are em(device independent).) ) c++-annotations-12.5.0/yo/string/stringview.yo0000644000175000017500000000514614466730207020214 0ustar frankfrankIn addition to the class tt(std::string) the class tt(std::string_view) can be used as a wrapper-class of tt(char) arrays. The class tt(string_view) can be considered a light-weight tt(string) class. Before using tt(std::string_view) objects the tthi(string_view) header file must have been included. In addition to the standard constructors (default, copy, move) it offers the following constructors: itemization( itt(constexpr string_view(char const *src, size_t nChars)), constructs a tt(string_view) object from the first tt(nChars) characters of tt(src). The characters in the range rangett(src, src + nChars) may be 0-valued characters; itt(constexpr string_view(char const *src)), constructs a tt(string_view) object from the NTBS starting at tt(src). The argument passed to this constructor may not be a null pointer; itt(constexpr string_view(Iterator begin, Iterator end)), constructs a tt(string_view) object from the characters in the iterator-range rangett(begin, end). ) A tt(string_view) object does not contain its own copy of the initialized data. Instead, it refers to the characters that were used when it was initially constructed. E.g., the following program produces unpredictable output, but when the tt(hello) array is defined as a static array it shows em(hello): verb( #include #include using namespace std; string_view fun() { char hello[] = "hello"; return { hello }; } int main() { string_view obj = fun(); cout << obj << '\n'; }) The tt(std::string_view) class provides the same members as tt(std::string), except for members extending the tt(string_view's) characters (neither appending nor inserting characters is possible). However, tt(string_view) objects em(can) modify their characters (using the index operator or tt(at) member). The tt(string_view) class also offers some extra members: itemization( ithtq(remove_prefix)(remove_prefix(size_t step)) (moves the begin of the object's character range forward by tt(step) positions.) ithtq(remove_suffix)(remove_suffix(size_t step)) (moves the end of the object's character range backward by tt(step) positions.) ithtq(operator""sv)(constexpr string_view operator""sv(char const *str, size_t len)) (returns a tt(string_view) object containing tt(len) characters of tt(str).) ) Like tt(std::string) the tt(std::string_view) class provides hashing facilities, so tt(string_view) objects can be used as keys in, e.g., tt(map) containers (cf. chapter ref(CONTAINERS)). c++-annotations-12.5.0/yo/advancedtemplates/0000755000175000017500000000000014612153140017576 5ustar frankfrankc++-annotations-12.5.0/yo/advancedtemplates/errorcategory.yo0000644000175000017500000001216114466730207023053 0ustar frankfrankIn the previous section the error code enumerations tt(CatErr) and tt(Cond) were developed. The values of these enumerations specify, respectively, the direct and the platform independent causes of errors that may be encountered in the context of the new error category developed in this section. Classes derived from tt(std::error_category) are designed as singleton classes and implement their own tt(name, message) and an tt(equivalent) members. Our class tt(Category) also declares a static member tt(instance) returning a reference to the class's singleton object, which is compile-time initialized and is available by the time tt(instance) is called. Alternatively a dedicated function (like tt(Category_category)), analogously to the function tt(generic_category), returning a reference to the tt(Category) object could be defined. tt(CatErr) values, tt(Cond) values and textual descriptions of tt(CatErr's) values are combined in a tt(std::unordered_map) using tt(CatErr) as key, and a tt(struct POD) as value type. This map allows us to retrieve the platform independent error types and the descriptions that are associated with tt(CatErr) values. Here is the interface of the class tt(Category): verbinsert(-s4 //category examples/errcode/category/category.h) Its tt(unordered_map s_map) provides the tt(Cond) values and verbal descriptions of the tt(CatErr) values given those tt(CatErr) values: verbinsert(-s4 //data examples/errcode/category/data.cc) The functions tt(make_error_code) and tt(make_error_condition) return, respectively, tt(error_code) and tt(error_condition) objects from, respectively, tt(CatErr) values and tt(Cond) values. Their declarations can be provided below the tt(Category) class interface and their implementations pass the tt(Category) object to their constructors: verbinsert(-s4 //make examples/errcode/category/makeerrorcode.cc) verbinsert(-s4 //make examples/errcode/category/makeerrorcondition.cc) The member tt(name) em(must) be defined by classes derived from tt(error_category). It simply returns a short string naming the category (e.g., tt("Category") for our tt(Category) class). Likewise, the member tt(message) em(must) be redefined. Its implementation usually is slightly more complex than tt(name's) implementation: it expects a (cast to an tt(int)) tt(CatErr) value and uses that value to find the corresponding textual description in tt(s_map). If found the description is returned; if not found then a short fallback message is returned: verbinsert(-s4 //msg examples/errcode/category/message.cc) The member tt(default_error_condition) receives a (cast to tt(int)) tt(CatErr) value. That value is used to find the associated tt(Cond) value. If the tt(int) received by the function does not represent a valid tt(CatErr) value then the fallback value tt(Cond::NoCond) is used. The function returns an tt(error_condition) object created by tt(make_error_condition) which receives the determined tt(Cond) value as its argument: verbinsert(-s4 //def examples/errcode/category/defaulterrorcondition.cc) What's left is implementing the two tt(equivalent) members. The first tt(equivalent) member (receiving a reference to an tt(error_code) object and a (cast to tt(int)) tt(Cond) value) determines the equivalence of the tt(Cond) value that is associated with the tt(error_code) object and the tt(Cond) value that is specified as the function's second argument. If these values are equal and the tt(error_code) object's category is equal to tt(Category) then the equivalence has been established and tt(true) is returned. Here is its implementation: verbinsert(-s4 //equiv examples/errcode/category/equivalent1.cc) The second tt(equivalent) member (receiving (as an tt(int)) tt(CatErr) value and an tt(error_condition) object) determines the equivalence of an tt(error_condition) object that is constructed from the tt(Cond) value that is associated with the tt(CatErr) value that was passed (as tt(int)) to the function and the tt(error_condition) object that was passed to the function as its second argument. Here a prerequisite for concluding equivalence is that the error condition's category is tt(Category). If that's the case then the function returns tt(true) if its tt(int) argument equals zero and the tt(condition) object also indicates no error. Alternatively, if the tt(condition) argument is equal to the tt(error_condition) object made from the tt(Cond) value associated with the tt(CatErr) value passed to the function as its first argument the equivalence has also been established and tt(true) is returned. Here is its implementation: verbinsert(-s4 //equiv examples/errcode/category/equivalent2.cc) So, in order to define your own category: itemization( it() define an enumeration which is `promoted' to an tt(error_code_enum); it() define an enumeration which is promoted to an tt(error_condition_enum); it() define a new tt(error_category) class by deriving a class from tt(std::error_category), define it as a singleton class and override its tt(default_error_condition, equivalent, message,) and tt(name) members. ) c++-annotations-12.5.0/yo/advancedtemplates/examples/0000755000175000017500000000000014624637124021430 5ustar frankfrankc++-annotations-12.5.0/yo/advancedtemplates/examples/typeat.cc0000664000175000017500000000132214624637130023242 0ustar frankfrank#include #include #include "typeat.h" using namespace std; int main() { //EXAMPLE using list3 = TypeList; // TypeAt<3, list3>::Type invalid; TypeAt<0, list3>::Type intVariable = 13; TypeAt<2, list3>::Type boolVariable = true; cout << "The size of the first type is " << sizeof(TypeAt<0, list3>::Type) << ", " "the size of the third type is " << sizeof(TypeAt<2, list3>::Type) << "\n"; if (typeid(TypeAt<1, list3>::Type) == typeid(char)) cout << "The typelist's 2nd type is char\n"; if (typeid(TypeAt<2, list3>::Type) != typeid(char)) cout << "The typelist's 3nd type is not char\n"; //= } c++-annotations-12.5.0/yo/advancedtemplates/examples/append.h0000664000175000017500000000103714624637127023056 0ustar frankfrank#ifndef INCLUDED_APPEND_H_ #define INCLUDED_APPEND_H_ #include "typelist.h" //STRUCTS template struct Append; template struct Prefix; //= //ADDTYPE template struct Append, NewType> { using List = TypeList; }; template struct Prefix> { using List = TypeList; }; //= #endif c++-annotations-12.5.0/yo/advancedtemplates/examples/typeat.h0000664000175000017500000000130614624637127023114 0ustar frankfrank#ifndef INCLUDED_TYPEAT_H_ #define INCLUDED_TYPEAT_H_ #include "typelist.h" //TYPEAT template struct TypeAt; //= //INVALID template struct TypeAt> { static_assert(index < 0, "TypeAt index out of bounds"); using Type = TypeAt; }; //= //ZERO template struct TypeAt<0, TypeList> { using Type = Head; }; //= //TYPELIST template struct TypeAt> { using Type = typename TypeAt>::Type; }; //= #endif c++-annotations-12.5.0/yo/advancedtemplates/examples/basictraits.cc0000664000175000017500000000323614624637130024252 0ustar frankfrank#include #include "basictraits.h" using namespace std; int main() { //MAIN cout << "int: plain type? " << BasicTraits::isPlainType << "\n" "int: ptr? " << BasicTraits::isPointerType << "\n" "int: const? " << BasicTraits::isConst << "\n" "int *: ptr? " << BasicTraits::isPointerType << "\n" "int const *: ptr? " << BasicTraits::isPointerType << "\n" "int const: const? " << BasicTraits::isConst << "\n" "int: reference? " << BasicTraits::isReferenceType << "\n" "int &: reference? " << BasicTraits::isReferenceType << "\n" "int const &: ref ? " << BasicTraits::isReferenceType << "\n" "int const &: const ? " << BasicTraits::isConst << "\n" "int &&: r-reference? " << BasicTraits::isRvalueReferenceType << "\n" "int &&: const? " << BasicTraits::isConst << "\n" "int const &&: r-ref ? "<< BasicTraits:: isRvalueReferenceType << "\n" "int const &&: const ? "<< BasicTraits::isConst << "\n" "\n"; BasicTraits::ValueType value = 12; BasicTraits::RvalueRefType rvalue = int(10); BasicTraits::PtrType ptr = new int(14); cout << value << ' ' << rvalue << ' ' << *ptr << '\n'; //= } c++-annotations-12.5.0/yo/advancedtemplates/examples/userdefined.cc0000664000175000017500000000073514624637130024240 0ustar frankfrank#include using namespace std; template double _kmh(Chars ...chars); double _kmh() { return 0; } template struct factor { enum { value = 10 * factor::value }; }; template<> struct factor<0> { enum {value = 1}; }; template double _kmh(char c, Chars ...chars) { return (c - '0') * factor::value + _kmh(chars ...); } int main() { cout << _kmh('1', '2', '3') << '\n'; } c++-annotations-12.5.0/yo/advancedtemplates/examples/multi.h0000664000175000017500000000702014624637127022737 0ustar frankfrank#include template struct TypeList { TypeList(TypeList const &) = delete; enum { size = sizeof ...(Types) }; }; //VECTOR template struct Vector: public std::vector { Vector(std::initializer_list iniValues) : std::vector(iniValues) {} }; //= //UWRAP template struct UWrap: public Type { UWrap(Type const &type) : Type(type) {} }; //= //MULTIBASE template struct MultiBase; //= //MULTIBASEREC template struct MultiBase : public UWrap, public MultiBase { using Type = PolicyT1; using Base = MultiBase; MultiBase(PolicyT1 && policyt1, PolicyTypes &&...policytypes) : UWrap(std::forward(policyt1)), MultiBase( std::forward(policytypes)...) {} }; //= //MULTIBASEDONE template struct MultiBase {}; //= //MULTI template

Frank B. Brokken (f.b.brokken@rug.nl)