Changes in / [32490deb:c75b30a]
- Files:
-
- 22 edited
-
doc/LaTeXmacros/common.sty (modified) (2 diffs)
-
doc/LaTeXmacros/common.tex (modified) (2 diffs)
-
doc/bibliography/pl.bib (modified) (99 diffs)
-
doc/papers/llheap/Paper.tex (modified) (19 diffs)
-
doc/proposals/enum.tex (modified) (49 diffs)
-
doc/uC++toCFA/Makefile (modified) (1 diff)
-
doc/uC++toCFA/uC++toCFA.tex (modified) (5 diffs)
-
doc/user/user.tex (modified) (151 diffs)
-
libcfa/src/collections/string_res.cfa (modified) (2 diffs)
-
libcfa/src/fstream.cfa (modified) (2 diffs)
-
libcfa/src/iostream.cfa (modified) (9 diffs)
-
libcfa/src/iostream.hfa (modified) (10 diffs)
-
src/Common/utility.h (modified) (1 diff)
-
src/ResolvExpr/Resolver.cc (modified) (1 diff)
-
tests/collections/.expect/string-istream-manip.txt (modified) (2 diffs)
-
tests/collections/.in/string-istream-manip.txt (modified) (2 diffs)
-
tests/collections/string-istream-manip.cfa (modified) (2 diffs)
-
tests/io/.expect/manipulatorsInput.arm64.txt (modified) (1 diff)
-
tests/io/.expect/manipulatorsInput.x64.txt (modified) (1 diff)
-
tests/io/.expect/manipulatorsInput.x86.txt (modified) (1 diff)
-
tests/io/.in/manipulatorsInput.txt (modified) (4 diffs)
-
tests/io/manipulatorsInput.cfa (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.sty
r32490deb rc75b30a 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Jan 21 13:17:48202414 %% Update Count : 63 313 %% Last Modified On : Sun Jan 14 12:28:26 2024 14 %% Update Count : 631 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 270 270 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly 271 271 \newlength{\columnposn} 272 \setlength{\gcolumnposn}{ 3in}272 \setlength{\gcolumnposn}{2.75in} 273 273 \setlength{\columnposn}{\gcolumnposn} 274 274 \newcommand{\setgcolumn}[1]{\global\gcolumnposn=#1\global\columnposn=\gcolumnposn} -
doc/LaTeXmacros/common.tex
r32490deb rc75b30a 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Wed Jan 24 08:43:57202414 %% Update Count : 59 313 %% Last Modified On : Sun Jan 14 17:59:02 2024 14 %% Update Count : 592 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 273 273 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly 274 274 \newlength{\columnposn} 275 \setlength{\gcolumnposn}{ 3in}275 \setlength{\gcolumnposn}{2.75in} 276 276 \setlength{\columnposn}{\gcolumnposn} 277 277 \newcommand{\setgcolumn}[1]{\global\gcolumnposn=#1\global\columnposn=\gcolumnposn} -
doc/bibliography/pl.bib
r32490deb rc75b30a 219 219 title = {Actor Benchmarks}, 220 220 author = {Peter A. Buhr and Colby A. Parsons}, 221 howpublished= {\ url{https://github.com/pabuhr/ActorExperiments}},221 howpublished= {\href{https://github.com/pabuhr/ActorExperiments}{https://\-github.com/\-pabuhr/\-ActorExperiments}}, 222 222 year = 2022, 223 223 } … … 296 296 contributer = {pabuhr@plg}, 297 297 author = {Ada16}, 298 title = {Ada Reference Manual ISO/IEC 8652:2012(E) with COR.1:2016},298 title = {Ada Reference Manual ISO/IEC 8652:2012(E) with COR.1:2016}, 299 299 edition = {3rd with Technical Corrigendum 1 for Ada 2012}, 300 300 organization= {AXE Consultants}, … … 416 416 address = {Waterloo, Ontario, Canada, N2L 3G1}, 417 417 optnote = {\textsf{http://uwspace.uwaterloo.ca/\-bitstream/10012/\-5751\-/1/Krischer\_Roy.pdf}}, 418 note = {\ url{http://uwspace.uwaterloo.ca/bitstream/10012/5751/1/Krischer_Roy.pdf}},418 note = {\href{http://uwspace.uwaterloo.ca/bitstream/10012/5751/1/Krischer_Roy.pdf}{http://uwspace.uwaterloo.ca/\-bitstream/10012/\-5751\-/1/Krischer\_Roy.pdf}}, 419 419 } 420 420 … … 430 430 number = 5, 431 431 pages = {1005-1042}, 432 optnote = {\ url{https://onlinelibrary.wiley.com/doi/10.1002/spe.2925}},432 optnote = {\href{https://onlinelibrary.wiley.com/doi/10.1002/spe.2925}{https://\-onlinelibrary.wiley.com/\-doi/\-10.1002/\-spe.2925}}, 433 433 } 434 434 … … 761 761 pages = {145-160}, 762 762 publisher = {{USENIX} Association}, 763 note = {\ url{https://www.usenix.org/conference/osdi18/presentation/qin}},763 note = {\href{https://www.usenix.org/conference/osdi18/presentation/qin}{https://\-www.usenix.org/\-conference/\-osdi18/\-presentation/\-qin}}, 764 764 } 765 765 … … 839 839 title = {Async Await}, 840 840 author = {{WikipediA}}, 841 howpublished= {\ url{https://en.wikipedia.org/wiki/Async/await}},841 howpublished= {\href{https://en.wikipedia.org/wiki/Async/await}{https://\-en.wikipedia.org/\-wiki/\-Async/\-await}}, 842 842 year = 2022, 843 843 } … … 928 928 institution = {Carnegie Mellon University}, 929 929 address = {California Institute of Technology, Pasadena, CA, USA}, 930 note = {\ url{http://www.cs.cmu.edu/~acw/15740/paper.pdf}},930 note = {\href{http://www.cs.cmu.edu/~acw/15740/paper.pdf}{http://\-www.cs.cmu.edu/\-$\sim$acw/\-15740/\-paper.pdf}, Accessed May 2014}, 931 931 year = 2009, 932 932 } … … 1034 1034 title = {Boost Coroutine Library}, 1035 1035 year = 2015, 1036 howpublished= {\url{http://www.boost.org/doc/libs/1_61_0/libs/coroutine/doc/html/index.html}}, 1036 howpublished= {\href{http://www.boost.org/doc/libs/1_61_0/libs/coroutine/doc/html/index.html} 1037 {http://www.boost.org/\-doc/\-libs/1\_61\_0/\-libs/\-coroutine/\-doc/\-html/\-index.html}}, 1037 1038 } 1038 1039 … … 1043 1044 title = {Boost Thread Library}, 1044 1045 year = 2015, 1045 howpublished= {\url{https://www.boost.org/doc/libs/1_61_0/doc/html/thread.html}}, 1046 howpublished= {\href{https://www.boost.org/doc/libs/1_61_0/doc/html/thread.html} 1047 {https://\-www.boost.org/\-doc/\-libs/\-1\_61\_0/\-doc/\-html/\-thread.html}}, 1046 1048 } 1047 1049 … … 1054 1056 month = oct, 1055 1057 type = {Diplomarbeit}, 1056 note = {\ url{https://plg.uwaterloo.ca/~usystem/theses/KrischerThesis.pdf}},1058 note = {\href{https://plg.uwaterloo.ca/~usystem/theses/KrischerThesis.pdf}{https://\-plg.uwaterloo.ca/\-$\sim$usystem/\-theses/\-KrischerThesis.pdf}}, 1057 1059 } 1058 1060 … … 1146 1148 address = {Geneva, Switzerland}, 1147 1149 year = 1999, 1148 note = {\ url{https://webstore.ansi.org/Standards/INCITS/INCITSISOIEC98991999R2005}},1150 note = {\href{https://webstore.ansi.org/Standards/INCITS/INCITSISOIEC98991999R2005}{https://webstore.ansi.org/\-Standards/\-INCITS/\-INCITSISOIEC98991999R2005}}, 1149 1151 } 1150 1152 … … 1158 1160 address = {Geneva, Switzerland}, 1159 1161 year = 2012, 1160 note = {\ url{https://www.iso.org/standard/57853.html}},1162 note = {\href{https://www.iso.org/standard/57853.html}{https://\-www.iso.org/\-standard/\-57853.html}}, 1161 1163 } 1162 1164 … … 1169 1171 address = {Geneva, Switzerland}, 1170 1172 year = 2015, 1171 note = {\ url{https://www.iso.org/standard/64031.html}},1173 note = {\href{https://www.iso.org/standard/64031.html}{https://\-www.iso.org/\-standard/\-64031.html}}, 1172 1174 } 1173 1175 … … 1196 1198 month = aug, 1197 1199 year = {2020}, 1198 note = {\ url{https://cforall.uwaterloo.ca/doc/Fangren_Yu_Report_S20.pdf}},1200 note = {\href{https://cforall.uwaterloo.ca/doc/Fangren_Yu_Report_S20.pdf}{https://\-cforall.uwaterloo.ca/\-doc/\-Fangren\_Yu\_Report\_S20.pdf}}, 1199 1201 } 1200 1202 … … 1210 1212 year = 2018, 1211 1213 pages = {2111-2146}, 1212 optnote = {\ url{http://dx.doi.org/10.1002/spe.2624}},1214 optnote = {\href{http://dx.doi.org/10.1002/spe.2624}{http://\-dx.doi.org/\-10.1002/\-spe.2624}}, 1213 1215 } 1214 1216 … … 1217 1219 key = {Cforall Benchmarks}, 1218 1220 author = {{\textsf{C}{$\mathbf{\forall}$} Benchmarks}}, 1219 howpublished= {\ url{https://github.com/cforall/ConcurrentBenchmarks_SPE20}},1221 howpublished= {\href{https://github.com/cforall/ConcurrentBenchmarks_SPE20}{https://\-github.com/\-cforall/\-ConcurrentBenchmarks\_SPE20}}, 1220 1222 } 1221 1223 … … 1224 1226 key = {Cforall}, 1225 1227 author = {{\textsf{C}{$\mathbf{\forall}$} Features}}, 1226 howpublished= {\ url{https://plg.uwaterloo.ca/~cforall/features}},1228 howpublished= {\href{https://plg.uwaterloo.ca/~cforall/features}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-features}}, 1227 1229 } 1228 1230 … … 1243 1245 title = {\textsf{C}$\mathbf{\forall}$ Stack Evaluation Programs}, 1244 1246 year = 2018, 1245 howpublished= {\ url{https://cforall.uwaterloo.ca/CFAStackEvaluation.zip}},1247 howpublished= {\href{https://cforall.uwaterloo.ca/CFAStackEvaluation.zip}{https://cforall.uwaterloo.ca/\-CFAStackEvaluation.zip}}, 1246 1248 } 1247 1249 … … 1254 1256 year = 2004, 1255 1257 address = {Waterloo, Ontario, Canada, N2L 3G1}, 1256 note = {\ url{http://plg.uwaterloo.ca/theses/EstevesThesis.pdf}},1258 note = {\href{http://plg.uwaterloo.ca/theses/EstevesThesis.pdf}{http://\-plg.uwaterloo.ca/\-theses/\-EstevesThesis.pdf}}, 1257 1259 } 1258 1260 … … 1264 1266 year = 2019, 1265 1267 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 1266 note = {\ url{https://uwspace.uwaterloo.ca/handle/10012/14584}},1268 note = {\href{https://uwspace.uwaterloo.ca/handle/10012/14584}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-14584}}, 1267 1269 } 1268 1270 … … 1421 1423 month = oct, 1422 1424 year = 2001, 1423 note = {\ url{http://plg.uwaterloo.ca/~cforall/cfa.ps}},1425 note = {\href{http://plg.uwaterloo.ca/~cforall/cfa.ps}{http://\-plg.uwaterloo.ca/\-$\sim$cforall/\-cfa.ps}}, 1424 1426 } 1425 1427 … … 1459 1461 contributer = {a3moss@uwaterloo.ca}, 1460 1462 title = {Clang: a {C} language family frontend for {LLVM}}, 1461 howpublished= {\ url{https://clang.llvm.org/}}1463 howpublished= {\href{https://clang.llvm.org/}{https://\-clang.llvm.org/}} 1462 1464 } 1463 1465 … … 1525 1527 address = {Geneva, Switzerland}, 1526 1528 year = 2014, 1527 note = {\ url{https://www.iso.org/standard/51416.html}},1529 note = {\href{https://www.iso.org/standard/51416.html}{https://\-www.iso.org/\-standard/\-51416.html}}, 1528 1530 } 1529 1531 … … 1666 1668 publisher = {Prentice-Hall}, 1667 1669 address = {Upper Saddle River, NJ, USA}, 1668 note = {\ url{http://www.usingcsp.com/cspbook.pdf}},1670 note = {\href{http://www.usingcsp.com/cspbook.pdf}{http://\-www.usingcsp.com/\-cspbook.pdf}}, 1669 1671 } 1670 1672 … … 1731 1733 month = sep, 1732 1734 address = {Waterloo, Ontario, Canada, N2L 3G1}, 1733 note = {\ url{http://plg.uwaterloo.ca/theses/MokThesis.pdf}},1735 note = {\href{http://plg.uwaterloo.ca/theses/MokThesis.pdf}{http://\-plg.uwaterloo.ca/\-theses/\-MokThesis.pdf}}, 1734 1736 } 1735 1737 … … 1806 1808 author = {Peter A. Buhr and David Dice and Wim H. Hesselink}, 1807 1809 title = {concurrent-locking}, 1808 howpublished= {\ url{https://github.com/pabuhr/concurrent-locking}},1810 howpublished= {\href{https://github.com/pabuhr/concurrent-locking}{https://\-github.com/\-pabuhr/\-concurrent-locking}}, 1809 1811 } 1810 1812 … … 1956 1958 year = 2015, 1957 1959 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 1958 note = {\ url{https://uwspace.uwaterloo.ca/handle/10012/10013}},1960 note = {\href{https://uwspace.uwaterloo.ca/handle/10012/10013}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-10013}}, 1959 1961 } 1960 1962 … … 2096 2098 month = oct, 2097 2099 year = 2010, 2098 howpublished= {\url{https://www.airs.com/blog/archives/428}}, 2100 howpublished= {\href{https://www.airs.com/blog/archives/428} 2101 {https://www.airs.com/\-blog/\-archives/\-428}}, 2099 2102 } 2100 2103 … … 2107 2110 year = 1992, 2108 2111 address = {Waterloo, Ontario, Canada, N2L 3G1}, 2109 note = {\ url{http://plg.uwaterloo.ca/theses/DitchfieldThesis.pdf}}2112 note = {\href{http://plg.uwaterloo.ca/theses/DitchfieldThesis.pdf}{http://\-plg.uwaterloo.ca/\-theses/\-DitchfieldThesis.pdf}} 2110 2113 } 2111 2114 … … 2177 2180 author = {Glen Ditchfield}, 2178 2181 title = {Conversions for \textsf{C}$\mathbf{\forall}$}, 2179 note = {\ url{http://plg.uwaterloo.ca/~cforall/Conversions/index.html}},2182 note = {\href{http://plg.uwaterloo.ca/~cforall/Conversions/index.html}{http://\-plg.uwaterloo.ca/\-$\sim$cforall/\-Conversions/\-index.html}}, 2180 2183 month = {Nov}, 2181 2184 year = {2002}, … … 2214 2217 year = 2019, 2215 2218 month = feb, 2216 howpublished= {\url{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0912r5.html}}, 2219 howpublished= {\href{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0912r5.html} 2220 {http://\-www.open-std.org/\-jtc1/\-sc22/\-wg21/\-docs/\-papers/\-2019/p0912r5.html}}, 2217 2221 } 2218 2222 … … 2225 2229 month = jun, 2226 2230 year = 2022, 2227 note = {\ url{https://en.cppreference.com/w/cpp/language/coroutines}},2231 note = {\href{https://en.cppreference.com/w/cpp/language/coroutines}{https://\-en.cppreference.com/\-w/\-cpp/\-language/\-coroutines}}, 2228 2232 } 2229 2233 … … 2279 2283 title = {CS343}, 2280 2284 year = 2018, 2281 howpublished= {\ url{https://www.student.cs.uwaterloo.ca/~cs343}},2285 howpublished= {\href{https://www.student.cs.uwaterloo.ca/~cs343}{https://\-www.student.cs.uwaterloo.ca/\-$\sim$cs343}}, 2282 2286 } 2283 2287 … … 2305 2309 address = {Vienna Virginia, U.S.A.}, 2306 2310 year = 2016, 2307 note = {\ url{http://dlang.org/spec/spec.html}},2311 note = {\href{http://dlang.org/spec/spec.html}{http://\-dlang.org/\-spec/\-spec.html}}, 2308 2312 } 2309 2313 … … 2782 2786 author = {Martin Odersky}, 2783 2787 title = {Dotty}, 2784 howpublished= {\ url{https://github.com/lampepfl/dotty}},2788 howpublished= {\href{https://github.com/lampepfl/dotty}{https://\-github.com/\-lampepfl/\-dotty}}, 2785 2789 note = {Acessed: 2019-02-22} 2786 2790 } … … 2793 2797 month = nov, 2794 2798 year = 1983, 2795 note = {\ url{http://www.lysator.liu.se/c/duffs-device.html}}2799 note = {\href{http://www.lysator.liu.se/c/duffs-device.html}{http://\-www.lysator.liu.se/\-c/\-duffs-device.html}} 2796 2800 } 2797 2801 … … 3029 3033 month = aug, 3030 3034 note = {WikipediA}, 3031 howpublished= {\url{http://www.akkadia.org/drepper/tls.pdf}}, 3035 howpublished= {\href{http://www.akkadia.org/drepper/tls.pdf} 3036 {http://\-www.akkadia.org/\-drepper/\-tls.pdf}}, 3032 3037 } 3033 3038 … … 3040 3045 month = may, 3041 3046 note = {Electronic Engineering Times}, 3042 howpublished= {\url{https://www.eetimes.com/author.asp?sectionid=36&doc_id=1287712}}, 3047 howpublished= {\href{https://www.eetimes.com/author.asp?sectionid=36&doc_id=1287712} 3048 {https://\-www.eetimes.com/\-author.asp?sectionid=\-36&doc_id=1287712}}, 3043 3049 } 3044 3050 … … 3153 3159 month = sep, 3154 3160 year = 2016, 3155 note = {\ url{http://erlang.org/doc/pdf/otp-system-documentation.pdf}},3161 note = {\href{http://erlang.org/doc/pdf/otp-system-documentation.pdf}{http://\-erlang.org/\-doc/\-pdf/\-otp-system-documentation.pdf}}, 3156 3162 } 3157 3163 … … 3476 3482 title = {Extensions to the {C} Language Family}, 3477 3483 year = 2014, 3478 howpublished= {\ url{https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/C-Extensions.html}},3484 howpublished= {\href{https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/C-Extensions.html}{https://\-gcc.gnu.org/\-onlinedocs/\-gcc-4.7.2/\-gcc/\-C\-Extensions.html}}, 3479 3485 } 3480 3486 … … 3559 3565 month = feb, 3560 3566 publisher = {John Wiley \& Sons}, 3561 note = {\ url{https://doi.org/10.1002/cpe.4183}}3567 note = {\href{https://doi.org/10.1002/cpe.4183}{https://\-doi.org/\-10.1002/\-cpe.4183}} 3562 3568 } 3563 3569 … … 3581 3587 title = {Fibers}, 3582 3588 organization= {Microsoft, Windows Development Center}, 3583 address = {\ url{https://docs.microsoft.com/en-us/windows/desktop/ProcThread/fibers}},3589 address = {\href{https://docs.microsoft.com/en-us/windows/desktop/ProcThread/fibers}{https://\-docs.microsoft.com/\-en-us/\-windows/\-desktop/\-ProcThread/\-fibers}}, 3584 3590 year = 2018, 3585 3591 } … … 3603 3609 month = jan, 3604 3610 address = {Waterloo, Ontario, Canada, N2L 3G1}, 3605 note = {\ url{http://uwspace.uwaterloo.ca/bitstream/10012/3501/1/Thesis.pdf}},3611 note = {\href{http://uwspace.uwaterloo.ca/bitstream/10012/3501/1/Thesis.pdf}{http://\-uwspace.uwaterloo.ca/\-bitstream/\-10012/\-3501/\-1/\-Thesis.pdf}}, 3606 3612 } 3607 3613 … … 3638 3644 title = {Facebook Open-source Library}, 3639 3645 organization= {Facebook}, 3640 address = {\ url{https://github.com/facebook/folly}},3646 address = {\href{https://github.com/facebook/folly}{https://\-github.com/\-facebook/\-folly}}, 3641 3647 year = 2018, 3642 3648 } … … 3679 3685 address = {Geneva, Switzerland}, 3680 3686 year = 2010, 3681 note = {\ url{https://www.iso.org/standard/50459.html}},3687 note = {\href{https://www.iso.org/standard/50459.html}{https://\-www.iso.org/\-standard/\-50459.html}}, 3682 3688 } 3683 3689 … … 3691 3697 address = {Geneva, Switzerland}, 3692 3698 year = 2018, 3693 note = {\ url{https://www.iso.org/standard/72320.html}},3699 note = {\href{https://www.iso.org/standard/72320.html}{https://\-www.iso.org/\-standard/\-72320.html}}, 3694 3700 } 3695 3701 … … 3922 3928 address = {GNU}, 3923 3929 year = 2016, 3924 note = {\ url{https://gmplib.org}},3930 note = {\href{https://gmplib.org}{https://\-gmplib.org}}, 3925 3931 } 3926 3932 … … 3933 3939 organization= {Google}, 3934 3940 year = 2009, 3935 note = {\ url{http://golang.org/ref/spec}},3941 note = {\href{http://golang.org/ref/spec}{http://\-golang.org/\-ref/\-spec}}, 3936 3942 } 3937 3943 … … 4037 4043 edition = {{S}imon {M}arlow}, 4038 4044 year = 2010, 4039 note = {\ url{https://haskell.org/definition/haskell2010.pdf}},4045 note = {\href{https://haskell.org/definition/haskell2010.pdf}{https://\-haskell.org/\-definition/\-haskell2010.pdf}}, 4040 4046 } 4041 4047 … … 4112 4118 number = 12, 4113 4119 pages = {2463-2500}, 4114 note = {\url{https://onlinelibrary.wiley.com/doi/10.1002/spe.3262} },4120 note = {\url{https://onlinelibrary.wiley.com/doi/10.1002/spe.3262}, 4115 4121 } 4116 4122 … … 4121 4127 year = 2019, 4122 4128 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 4123 note = {\ url{https://uwspace.uwaterloo.ca/handle/10012/14706}},4129 note = {\href{https://uwspace.uwaterloo.ca/handle/10012/14706}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-14706}}, 4124 4130 } 4125 4131 … … 4180 4186 month = sep, 4181 4187 publisher = {John Wiley \& Sons}, 4182 note = {\ url{https://doi.org/10.1002/cpe.4475}},4188 note = {\href{https://doi.org/10.1002/cpe.4475}{https://\-doi.org/\-10.1002/\-cpe.4475}}, 4183 4189 } 4184 4190 … … 4314 4320 year = 2003, 4315 4321 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 4316 note = {\ url{http://plg.uwaterloo.ca/theses/BilsonThesis.pdf}},4322 note = {\href{http://plg.uwaterloo.ca/theses/BilsonThesis.pdf}{http://\-plg.uwaterloo.ca/\-theses/\-BilsonThesis.pdf}}, 4317 4323 } 4318 4324 … … 4727 4733 title = {JDK 1.1 for Solaris Developer's Guide}, 4728 4734 publisher = {Oracle}, 4729 address = {\ url{https://docs.oracle.com/cd/E19455-01/806-3461/6jck06gqk/index.html#ch2mt-41}},4735 address = {\href{https://docs.oracle.com/cd/E19455-01/806-3461/6jck06gqk/index.html#ch2mt-41}{https://\-docs.oracle.com/\-cd/\-E19455-01/\-806-3461/\-6jck06gqk/\-index.html\#ch2mt-41}}, 4730 4736 year = 2010, 4731 4737 } … … 4738 4744 organization= {Oracle}, 4739 4745 year = 2014, 4740 note = {\ url{http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html}},4746 note = {\href{http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html}{http://docs.oracle.com/\-javase/7/\-docs/\-api/\-java/\-util/\-concurrent/\-package-summary.html}}, 4741 4747 } 4742 4748 … … 4867 4873 title = {Labels as Values}, 4868 4874 year = {since gcc-3}, 4869 howpublished= {\url{https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html}}, 4875 howpublished= {\href{https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html} 4876 {https:\-//gcc.gnu.org/\-onlinedocs/\-gcc/\-Labels-as-Values.html}}, 4870 4877 } 4871 4878 … … 4924 4931 title = {libdill Thread Library}, 4925 4932 year = 2019, 4926 howpublished= {\url{http://libdill.org/libdill-2.14.tar.gz}}, 4933 howpublished= {\href{http://libdill.org/libdill-2.14.tar.gz} 4934 {http://\-libdill.org/\-libdill-2.14.tar.gz}}, 4927 4935 } 4928 4936 … … 4931 4939 author = {Martin Karsten}, 4932 4940 title = {{libfibre:~User-Level Threading Runtime}}, 4933 howpublished= {\ url{https://git.uwaterloo.ca/mkarsten/libfibre}},4941 howpublished= {\href{https://git.uwaterloo.ca/mkarsten/libfibre}{https://\-git.uwaterloo.ca/\-mkarsten/\-libfibre}}, 4934 4942 note = {[Online; accessed 2020-04-15]}, 4935 4943 } … … 4954 4962 title = {{G}o-style concurrency in {C}, Version 1.18}, 4955 4963 organization= {libmill}, 4956 address = {\ url{http://libmill.org/documentation.html}},4964 address = {\href{http://libmill.org/documentation.html}{http://\-libmill.org/\-documentation.html}}, 4957 4965 month = jan, 4958 4966 year = 2017, … … 5030 5038 month = jan, 5031 5039 year = 2017, 5032 howpublished= {\url{http://smallcultfollowing.com/babysteps/blog/2017/01/26/lowering-rust-traits-to-logic/}}, 5040 howpublished= {\href{http://smallcultfollowing.com/babysteps/blog/2017/01/26/lowering-rust-traits-to-logic/} 5041 {http://smallcultfollowing.com/\-babysteps/\-blog/\-2017/\-01/\-26/\-lowering-rust-traits-to-logic/}}, 5033 5042 optnote = {Accessed: 2019-01}, 5034 5043 } … … 5054 5063 title = {Lua 5.4 Reference Manual}, 5055 5064 organization= {Pontifical Catholic University}, 5056 address = {\ url{https://www.lua.org/manual/5.4}},5065 address = {\href{https://www.lua.org/manual/5.4}{https://\-www.lua.org/\-manual/\-5.4}}, 5057 5066 year = 2020, 5058 5067 } … … 5075 5084 title = {Making arbitrarily-large binaries from fixed-size {C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} code}, 5076 5085 year = 2016, 5077 howpublished= {\url{http://blog.reverberate.org/2016/01/making-arbitrarily-large-binaries-from.html}}, 5086 howpublished= {\href{http://blog.reverberate.org/2016/01/making-arbitrarily-large-binaries-from.html} 5087 {http://blog.reverberate.org/\-2016/\-01/\-making-arbitrarily-large-binaries-from.html}}, 5078 5088 optnote = {Accessed: 2016-09}, 5079 5089 } … … 5108 5118 title = {Marcel Thread Library}, 5109 5119 year = 2011, 5110 howpublished= {\url{https://gforge.inria.fr/frs/download.php/file/28643/marcel-2.99.3.tar.gz}}, 5120 howpublished= {\href{https://gforge.inria.fr/frs/download.php/file/28643/marcel-2.99.3.tar.gz} 5121 {https://\-gforge.inria.fr/\-frs/\-download.php/\-file/\-28643/\-marcel-2.99.3.tar.gz}}, 5111 5122 } 5112 5123 … … 5253 5264 month = sep, 5254 5265 year = 1994, 5255 note = {\ url{https://plg.uwaterloo.ca/~usystem/pub/uSystem/uSystem.pdf}},5266 note = {\href{https://plg.uwaterloo.ca/~usystem/pub/uSystem/uSystem.pdf}{https://\-plg.uwaterloo.ca/\-$\sim$usystem/\-pub/\-uSystem/\-uSystem.pdf}}, 5256 5267 } 5257 5268 … … 5452 5463 month = jun, 5453 5464 year = 2015, 5454 note = {\ url{http://www.mpi-forum.org/docs/mpi-3.1/mpi31-report.pdf}},5465 note = {\href{http://www.mpi-forum.org/docs/mpi-3.1/mpi31-report.pdf}{http://www.mpi-forum.org/\-docs/\-mpi-3.1/\-mpi31-report.pdf}}, 5455 5466 } 5456 5467 … … 5602 5613 year = 1980, 5603 5614 pages = {833-842}, 5604 note = {\ url{http://groups.csail.mit.edu/tds/papers/Lynch/allertonconf.pdf}},5615 note = {\href{http://groups.csail.mit.edu/tds/papers/Lynch/allertonconf.pdf}{http://\-groups.csail.mit.edu/\-tds/\-papers/\-Lynch/\-allertonconf.pdf} [Accessed on March 2014]}, 5605 5616 optnote = {\textsf{http://\-groups.csail.mit.edu/\-tds/\-papers/\-Lynch/\-allertonconf.pdf}}, 5606 5617 } … … 5628 5639 institution = {Red Hat}, 5629 5640 year = 2003, 5630 note = {\ url{http://www.cs.utexas.edu/~witchel/372/lectures/POSIX_Linux_Threading.pdf}},5641 note = {\href{http://www.cs.utexas.edu/~witchel/372/lectures/POSIX_Linux_Threading.pdf}{http://www.cs.utexas.edu/\-$\sim$witchel/\-372/\-lectures/\-POSIX\_Linux\_Threading.pdf}}, 5631 5642 } 5632 5643 … … 5638 5649 organization= {{gcc} 9.3 Manual}, 5639 5650 year = 2019, 5640 note = {\ url{https://gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/Nested-Functions.html}},5651 note = {\href{https://gcc.gnu.org/onlinedocs/gcc-9.3.0/gcc/Nested-Functions.html}{https://\-gcc.gnu.org/\-onlinedocs/\-gcc-9.3.0/\-gcc/\-Nested-Functions.html}}, 5641 5652 } 5642 5653 … … 5707 5718 year = 1990, 5708 5719 pages = {41-51}, 5709 note = {\ url{http://doc.cat-v.org/bell_labs/new_c_compilers/new_c_compiler.pdf}},5720 note = {\href{http://doc.cat-v.org/bell_labs/new_c_compilers/new_c_compiler.pdf}{http://\-doc.cat-v.org/\-bell\_labs/\-new\_c\_compilers/\-new\_c\_compiler.pdf}}, 5710 5721 } 5711 5722 … … 5770 5781 key = {nginx}, 5771 5782 author = {{NGINX}}, 5772 howpublished= {\ url{https://www.nginx.com}},5783 howpublished= {\href{https://www.nginx.com}{https://\-www.nginx.com}}, 5773 5784 } 5774 5785 … … 5899 5910 publisher = {Apple Inc.}, 5900 5911 year = 2014, 5901 howpublished= {\ url{https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC}},5912 howpublished= {\href{https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC}{https://\-developer.apple.com/\-library/archive/\-documentation/\-Cocoa/\-Conceptual/\-ProgrammingWithObjectiveC}}, 5902 5913 } 5903 5914 … … 5908 5919 title = {{X}code 7 Release Notes}, 5909 5920 year = 2015, 5910 howpublished= {\ url{https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc7_release_notes.html}},5921 howpublished= {\href{https://developer.apple.com/library/content/documentation/Xcode/Conceptual/RN-Xcode-Archive/Chapters/xc7_release_notes.html}{https://\-developer.apple.com/\-library/\-content/\-documentation/\-Xcode/\-Conceptual/\-RN-Xcode-Archive/\-Chapters/\-xc7\_release\_notes.html}}, 5911 5922 } 5912 5923 … … 6041 6052 month = nov, 6042 6053 year = 2015, 6043 note = {\ url{https://www.openmp.org/wp-content/uploads/openmp-4.5.pdf}},6054 note = {\href{https://www.openmp.org/wp-content/uploads/openmp-4.5.pdf}{https://\-www.openmp.org/\-wp-content/\-uploads/\-openmp-4.5.pdf}}, 6044 6055 } 6045 6056 … … 6049 6060 title = {OpenTelemetry}, 6050 6061 author = {{Asynkron AB}}, 6051 howpublished= {\ url{https://proto.actor/docs/tracing}},6062 howpublished= {\href{https://proto.actor/docs/tracing}{https://\-proto.actor/\-docs/\-tracing}}, 6052 6063 year = 2022, 6053 6064 } … … 6450 6461 key = {perf}, 6451 6462 author = {perf}, 6452 howpublished= {\ url{https://perf.wiki.kernel.org/index.php/Tutorial}},6463 howpublished= {\href{https://perf.wiki.kernel.org/index.php/Tutorial}{https://\-perf.wiki.kernel.org/\-index.php/\-Tutorial}}, 6453 6464 } 6454 6465 … … 6459 6470 month = may, 6460 6471 year = 2012, 6461 howpublished= {\ url{http://cs.brown.edu/research/pubs/theses/masters/2012/verch.pdf}},6472 howpublished= {\href{http://cs.brown.edu/research/pubs/theses/masters/2012/verch.pdf}{http://cs.brown.edu/\-research/\-pubs/\-theses/\-masters/\-2012/\-verch.pdf}}, 6462 6473 } 6463 6474 … … 6858 6869 address = {Geneva, Switzerland}, 6859 6870 year = 1998, 6860 note = {\ url{https://www.iso.org/standard/25845.html}},6871 note = {\href{https://www.iso.org/standard/25845.html}{https://\-www.iso.org/\-standard/\-25845.html}}, 6861 6872 } 6862 6873 … … 6870 6881 address = {Geneva, Switzerland}, 6871 6882 year = 2014, 6872 note = {\ url{https://www.iso.org/standard/64029.html}},6883 note = {\href{https://www.iso.org/standard/64029.html}{https://\-www.iso.org/\-standard/\-64029.html}}, 6873 6884 } 6874 6885 … … 6882 6893 address = {Geneva, Switzerland}, 6883 6894 year = 2017, 6884 note = {\ url{https://www.iso.org/standard/68564.html}},6895 note = {\href{https://www.iso.org/standard/68564.html}{https://\-www.iso.org/\-standard/\-68564.html}}, 6885 6896 } 6886 6897 … … 7162 7173 author = {IEEE and {The Open Group}}, 7163 7174 year = 2018, 7164 howpublished= {\url{http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html}}, 7175 howpublished= {\href{http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html} 7176 {http://\-pubs.opengroup.org/\-onlinepubs/\-9699919799/\-basedefs/\-pthread.h.html}}, 7165 7177 } 7166 7178 … … 7171 7183 title = {Python Language Reference, Release 3.7.2}, 7172 7184 organization= {Python Software Foundation}, 7173 address = {\ url{https://docs.python.org/3/reference/index.html}},7185 address = {\href{https://docs.python.org/3/reference/index.html}{https://\-docs.python.org/\-3/\-reference/\-index.html}}, 7174 7186 year = 2018, 7175 7187 } … … 7226 7238 title = {Quasar Documentation, Release 0.8.0}, 7227 7239 organization= {Parallel Universe}, 7228 address = {\ url{http://docs.paralleluniverse.co/quasar}},7240 address = {\href{http://docs.paralleluniverse.co/quasar}{http://\-docs.paralleluniverse.co/\-quasar}}, 7229 7241 year = 2018, 7230 7242 } … … 7366 7378 month = apr, 7367 7379 type = {Diplomarbeit}, 7368 note = {\ url{https://plg.uwaterloo.ca/~usystem/theses/SchusterThesis.pdf}},7380 note = {\href{https://plg.uwaterloo.ca/~usystem/theses/SchusterThesis.pdf}{https://\-plg.uwaterloo.ca/\-$\sim$usystem/\-theses/\-SchusterThesis.pdf}}, 7369 7381 } 7370 7382 … … 7401 7413 year = 2017, 7402 7414 optaddress = {Waterloo, Ontario, Canada, N2L 3G1}, 7403 note = {\ url{https://uwspace.uwaterloo.ca/handle/10012/11830}},7415 note = {\href{https://uwspace.uwaterloo.ca/handle/10012/11830}{https://\-uwspace.uwaterloo.ca/\-handle/\-10012/\-11830}}, 7404 7416 } 7405 7417 … … 7479 7491 month = apr, 7480 7492 year = 2022, 7481 howpublished= {\ url{https://github.com/mjansson/rpmalloc}},7493 howpublished= {\href{https://github.com/mjansson/rpmalloc}{https://\-github.com/\-mjansson/\-rpmalloc}}, 7482 7494 } 7483 7495 … … 7489 7501 optaddress = {Rust Project Developers}, 7490 7502 year = 2015, 7491 note = {\ url{https://doc.rust-lang.org/reference.html}},7503 note = {\href{https://doc.rust-lang.org/reference.html}{https://\-doc.rust-lang\-.org/\-reference.html}}, 7492 7504 } 7493 7505 … … 7498 7510 title = {Ruby Documentation, Release 2.6.0}, 7499 7511 organization= {Python Software Foundation}, 7500 address = {\ url{https://www.ruby-lang.org/en/documentation}},7512 address = {\href{https://www.ruby-lang.org/en/documentation}{https://\-www.ruby-lang.org/\-en/\-documentation}}, 7501 7513 year = 2018, 7502 7514 } … … 7526 7538 address = {\'{E}cole Polytechnique F\'{e}d\'{e}rale de Lausanne}, 7527 7539 year = 2016, 7528 note = {\ url{http://www.scala-lang.org/files/archive/spec/2.11}},7540 note = {\href{http://www.scala-lang.org/files/archive/spec/2.11}{http://\-www.scala-lang.org/\-files/\-archive/\-spec/\-2.11}}, 7529 7541 } 7530 7542 … … 7687 7699 month = sep, 7688 7700 year = 1995, 7689 note = {\ url{http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-95-7.pdf}},7701 note = {\href{http://www.hpl.hp.com/techreports/Compaq-DEC/WRL-95-7.pdf}{http://www.hpl.hp.com/\-techreports/\-Compaq-DEC/\-WRL-95-7.pdf}, Reprinted in \cite{Adve95reprint}.}, 7690 7702 } 7691 7703 … … 7761 7773 month = may, 7762 7774 year = 2001, 7763 note = {\ url{http://www.python.org/peps/pep-0255.html}},7775 note = {\href{http://www.python.org/peps/pep-0255.html}{http://\-www.python.org/\-peps/\-pep-0255.html}}, 7764 7776 } 7765 7777 … … 8064 8076 organization= {IEEE and The Open Group}, 8065 8077 year = 2017, 8066 note = {\ url{https://pubs.opengroup.org/onlinepubs/9699919799}},8078 note = {\href{https://pubs.opengroup.org/onlinepubs/9699919799}{https://\-pubs.opengroup.org/\-onlinepubs/\-9699919799}}, 8067 8079 } 8068 8080 … … 8131 8143 pages = {1-6}, 8132 8144 numpages = {6}, 8133 howpublished= {\ url{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0144r0.pdf}},8145 howpublished= {\href{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0144r0.pdf}{http://\-www.open-std.org/\-jtc1/\-sc22/\-wg21/\-docs/\-papers/\-2015/\-p0144r0.pdf}}, 8134 8146 } 8135 8147 … … 8441 8453 key = {TIOBE Index}, 8442 8454 author = {{TIOBE Index}}, 8443 howpublished= {\ url{http://www.tiobe.com/tiobe_index}},8455 howpublished= {\href{http://www.tiobe.com/tiobe_index}{http://\-www.tiobe.com/\-tiobe\_index}}, 8444 8456 } 8445 8457 … … 8449 8461 title = {Thread (computing)}, 8450 8462 author = {{Threading Model}}, 8451 howpublished= {\ url{https://en.wikipedia.org/wiki/Thread_(computing)}},8463 howpublished= {\href{https://en.wikipedia.org/wiki/Thread_(computing)}{https://\-en.wikipedia.org/\-wiki/\-Thread\_\-(computing)}}, 8452 8464 } 8453 8465 … … 8457 8469 title = {{T}okio Asynchronous Runtime for {R}ust}, 8458 8470 author = {Tokio}, 8459 howpublished= {\ url{https://tokio.rs}},8471 howpublished= {\href{https://tokio.rs}{https://\-tokio.rs}}, 8460 8472 } 8461 8473 … … 8597 8609 key = {Trace Compass}, 8598 8610 author = {{T}race {C}ompass}, 8599 howpublished= {\ url{https://projects.eclipse.org/proposals/trace-compass}},8611 howpublished= {\href{https://projects.eclipse.org/proposals/trace-compass}{https://\-projects.eclipse.org/\-proposals/\-trace-compass}}, 8600 8612 } 8601 8613 … … 8656 8668 title = {Typed Actors}, 8657 8669 author = {{Lightbend}}, 8658 howpublished= {\ url{https://doc.akka.io/docs/akka/2.5/typed-actors.html}},8670 howpublished= {\href{https://doc.akka.io/docs/akka/2.5/typed-actors.html}{https://\-doc.akka.io/\-docs/\-akka/\-2.5/\-typed-actors.html}}, 8659 8671 year = 2022, 8660 8672 } … … 8926 8938 year = 2020, 8927 8939 note = {WikipediA}, 8928 howpublished= {\url{https://en.wikipedia.org/wiki/Visitor\_pattern}}, 8940 howpublished= {\href{https://en.wikipedia.org/wiki/Visitor\_pattern} 8941 {https://\-en.wikipedia.org/\-wiki/\-Visitor\_pattern}}, 8929 8942 } 8930 8943 … … 9028 9041 month = jun, 9029 9042 year = 1985, 9030 note = {\ url{http://www.hpl.hp.com/techreports/tandem/TR-85.7.pdf}},9043 note = {\href{http://www.hpl.hp.com/techreports/tandem/TR-85.7.pdf}{http://www.hpl.hp.com/\-techreports/\-tandem/\-TR-85.7.pdf}}, 9031 9044 } 9032 9045 -
doc/papers/llheap/Paper.tex
r32490deb rc75b30a 77 77 \lstset{ 78 78 columns=fullflexible, 79 basicstyle=\linespread{0.9}\sf, % reduce line spacing and use sanserif font 80 stringstyle=\small\tt, % use typewriter font 81 tabsize=5, % N space tabbing 82 xleftmargin=\parindentlnth, % indent code to paragraph indentation 83 escapechar=\$, % LaTeX escape in CFA code 84 %mathescape=true, % LaTeX math escape in CFA code $...$ 85 keepspaces=true, % 86 showstringspaces=false, % do not show spaces with cup 87 showlines=true, % show blank lines at end of code 88 aboveskip=4pt, % spacing above/below code block 89 belowskip=2pt, 90 numberstyle=\footnotesize\sf, % numbering style 91 moredelim=**[is][\color{red}]{@}{@}, 79 basicstyle=\linespread{0.9}\sf, % reduce line spacing and use sanserif font 80 stringstyle=\tt, % use typewriter font 81 tabsize=5, % N space tabbing 82 xleftmargin=\parindentlnth, % indent code to paragraph indentation 83 %mathescape=true, % LaTeX math escape in CFA code $...$ 84 escapechar=\$, % LaTeX escape in CFA code 85 keepspaces=true, % 86 showstringspaces=false, % do not show spaces with cup 87 showlines=true, % show blank lines at end of code 88 aboveskip=4pt, % spacing above/below code block 89 belowskip=3pt, 90 moredelim=**[is][\color{red}]{`}{`}, 92 91 }% lstset 93 92 … … 1083 1082 1084 1083 The primary design objective for llheap is low-latency across all allocator calls independent of application access-patterns and/or number of threads, \ie very seldom does the allocator have a delay during an allocator call. 1085 Excluded from the low-latency objective are (large) allocations requiring initialization, \eg zero fill, and/or data copying, which are outside the allocator's purview. 1084 (Large allocations requiring initialization, \eg zero fill, and/or copying are not covered by the low-latency objective.) 1086 1085 A direct consequence of this objective is very simple or no storage coalescing; 1087 1086 hence, llheap's design is willing to use more storage to lower latency. 1088 1087 This objective is apropos because systems research and industrial applications are striving for low latency and computers have huge amounts of RAM memory. 1089 Finally, llheap's performance should be comparable with the current best allocators , both in space and time(see performance comparison in Section~\ref{c:Performance}).1088 Finally, llheap's performance should be comparable with the current best allocators (see performance comparison in Section~\ref{c:Performance}). 1090 1089 1091 1090 % The objective of llheap's new design was to fulfill following requirements: … … 1206 1205 % \label{s:AllocationFastpath} 1207 1206 1208 llheap's design was reviewed and changed multiple times during its development, with the final choices are discussed here. 1207 llheap's design was reviewed and changed multiple times during its development. Only the final design choices are 1208 discussed in this paper. 1209 1209 (See~\cite{Zulfiqar22} for a discussion of alternate choices and reasons for rejecting them.) 1210 1210 All designs were analyzed for the allocation/free \newterm{fastpath}, \ie when an allocation can immediately return free storage or returned storage is not coalesced. 1211 The heap model cho sen is 1:1, which is the T:H model with T = H, where there is one thread-local heap for each KT.1211 The heap model choosen is 1:1, which is the T:H model with T = H, where there is one thread-local heap for each KT. 1212 1212 (See Figure~\ref{f:THSharedHeaps} but with a heap bucket per KT and no bucket or local-pool lock.) 1213 1213 Hence, immediately after a KT starts, its heap is created and just before a KT terminates, its heap is (logically) deleted. … … 1426 1426 1427 1427 1428 Algorithm~\ref{alg:heapObjectFreeOwn} shows the de allocation (free) outline for an object at address $A$ with ownership.1428 Algorithm~\ref{alg:heapObjectFreeOwn} shows the de-allocation (free) outline for an object at address $A$ with ownership. 1429 1429 First, the address is divided into small (@sbrk@) or large (@mmap@). 1430 1430 For large allocations, the storage is unmapped back to the OS. … … 1433 1433 If the bucket is not local to the thread, the allocation is pushed onto the owning thread's associated away stack. 1434 1434 1435 Algorithm~\ref{alg:heapObjectFreeNoOwn} shows the de allocation (free) outline for an object at address $A$ without ownership.1435 Algorithm~\ref{alg:heapObjectFreeNoOwn} shows the de-allocation (free) outline for an object at address $A$ without ownership. 1436 1436 The algorithm is the same as for ownership except if the bucket is not local to the thread. 1437 1437 Then the corresponding bucket of the owner thread is computed for the deallocating thread, and the allocation is pushed onto the deallocating thread's bucket. … … 1792 1792 The C dynamic-memory API is extended with the following routines: 1793 1793 1794 \medskip\noindent 1795 \lstinline{void * aalloc( size_t dim, size_t elemSize )} 1796 extends @calloc@ for allocating a dynamic array of objects with total size @dim@ $\times$ @elemSize@ but \emph{without} zero-filling the memory. 1797 @aalloc@ is significantly faster than @calloc@, which is the only alternative given by the standard memory-allocation routines for array allocation. 1794 \paragraph{\lstinline{void * aalloc( size_t dim, size_t elemSize )}} 1795 extends @calloc@ for allocating a dynamic array of objects without calculating the total size of array explicitly but \emph{without} zero-filling the memory. 1796 @aalloc@ is significantly faster than @calloc@, which is the only alternative given by the standard memory-allocation routines. 1797 1798 \noindent\textbf{Usage} 1799 @aalloc@ takes two parameters. 1800 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1801 \item 1802 @dim@: number of array objects 1803 \item 1804 @elemSize@: size of array object 1805 \end{itemize} 1798 1806 It returns the address of the dynamic array or @NULL@ if either @dim@ or @elemSize@ are zero. 1799 1807 1800 \medskip\noindent 1801 \lstinline{void * resize( void * oaddr, size_t size )} 1802 extends @realloc@ for resizing an existing allocation, @oaddr@, to the new @size@ (smaller or larger than previous) \emph{without} copying previous data into the new allocation or preserving sticky properties. 1808 \paragraph{\lstinline{void * resize( void * oaddr, size_t size )}} 1809 extends @realloc@ for resizing an existing allocation \emph{without} copying previous data into the new allocation or preserving sticky properties. 1803 1810 @resize@ is significantly faster than @realloc@, which is the only alternative. 1811 1812 \noindent\textbf{Usage} 1813 @resize@ takes two parameters. 1814 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1815 \item 1816 @oaddr@: address to be resized 1817 \item 1818 @size@: new allocation size (smaller or larger than previous) 1819 \end{itemize} 1804 1820 It returns the address of the old or new storage with the specified new size or @NULL@ if @size@ is zero. 1805 1821 1806 \medskip\noindent 1807 \lstinline{void * amemalign( size_t alignment, size_t dim, size_t elemSize )} 1808 extends @aalloc@ and @memalign@ for allocating a dynamic array of objects with the starting address on the @alignment@ boundary. 1822 \paragraph{\lstinline{void * amemalign( size_t alignment, size_t dim, size_t elemSize )}} 1823 extends @aalloc@ and @memalign@ for allocating an aligned dynamic array of objects. 1809 1824 Sets sticky alignment property. 1825 1826 \noindent\textbf{Usage} 1827 @amemalign@ takes three parameters. 1828 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1829 \item 1830 @alignment@: alignment requirement 1831 \item 1832 @dim@: number of array objects 1833 \item 1834 @elemSize@: size of array object 1835 \end{itemize} 1810 1836 It returns the address of the aligned dynamic-array or @NULL@ if either @dim@ or @elemSize@ are zero. 1811 1837 1812 \medskip\noindent 1813 \lstinline{void * cmemalign( size_t alignment, size_t dim, size_t elemSize )} 1838 \paragraph{\lstinline{void * cmemalign( size_t alignment, size_t dim, size_t elemSize )}} 1814 1839 extends @amemalign@ with zero fill and has the same usage as @amemalign@. 1815 1840 Sets sticky zero-fill and alignment property. 1816 1841 It returns the address of the aligned, zero-filled dynamic-array or @NULL@ if either @dim@ or @elemSize@ are zero. 1817 1842 1818 \medskip\noindent 1819 \lstinline{size_t malloc_alignment( void * addr )} 1820 returns the object alignment, where objects not allocated with alignment return the minimal allocation alignment. 1821 For use in aligning similar allocations. 1822 1823 \medskip\noindent 1824 \lstinline{bool malloc_zero_fill( void * addr )} 1825 returns true if the objects zero-fill sticky property is set and false otherwise. 1826 For use in zero filling similar allocations. 1827 1828 \medskip\noindent 1829 \lstinline{size_t malloc_size( void * addr )} 1830 returns the object's request size, which is updated when an object is resized or zero if @addr@ is @NULL@ (see also @malloc_usable_size@). 1831 For use in similar allocations. 1832 1833 \medskip\noindent 1834 \lstinline{int malloc_stats_fd( int fd )} 1835 changes the file descriptor where @malloc_stats@ writes statistics (default @stdout@) and returns the previous file descriptor. 1836 1837 \medskip\noindent 1838 \lstinline{size_t malloc_expansion()} 1843 \paragraph{\lstinline{size_t malloc_alignment( void * addr )}} 1844 returns the alignment of the dynamic object for use in aligning similar allocations. 1845 1846 \noindent\textbf{Usage} 1847 @malloc_alignment@ takes one parameter. 1848 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1849 \item 1850 @addr@: address of an allocated object. 1851 \end{itemize} 1852 It returns the alignment of the given object, where objects not allocated with alignment return the minimal allocation alignment. 1853 1854 \paragraph{\lstinline{bool malloc_zero_fill( void * addr )}} 1855 returns true if the object has the zero-fill sticky property for use in zero filling similar allocations. 1856 1857 \noindent\textbf{Usage} 1858 @malloc_zero_fill@ takes one parameters. 1859 1860 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1861 \item 1862 @addr@: address of an allocated object. 1863 \end{itemize} 1864 It returns true if the zero-fill sticky property is set and false otherwise. 1865 1866 \paragraph{\lstinline{size_t malloc_size( void * addr )}} 1867 returns the request size of the dynamic object (updated when an object is resized) for use in similar allocations. 1868 See also @malloc_usable_size@. 1869 1870 \noindent\textbf{Usage} 1871 @malloc_size@ takes one parameters. 1872 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1873 \item 1874 @addr@: address of an allocated object. 1875 \end{itemize} 1876 It returns the request size or zero if @addr@ is @NULL@. 1877 1878 \paragraph{\lstinline{int malloc_stats_fd( int fd )}} 1879 changes the file descriptor where @malloc_stats@ writes statistics (default @stdout@). 1880 1881 \noindent\textbf{Usage} 1882 @malloc_stats_fd@ takes one parameters. 1883 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1884 \item 1885 @fd@: file descriptor. 1886 \end{itemize} 1887 It returns the previous file descriptor. 1888 1889 \paragraph{\lstinline{size_t malloc_expansion()}} 1839 1890 \label{p:malloc_expansion} 1840 1891 set the amount (bytes) to extend the heap when there is insufficient free storage to service an allocation request. 1841 1892 It returns the heap extension size used throughout a program when requesting more memory from the system using @sbrk@ system-call, \ie called once at heap initialization. 1842 1893 1843 \medskip\noindent 1844 \lstinline{size_t malloc_mmap_start()} 1894 \paragraph{\lstinline{size_t malloc_mmap_start()}} 1845 1895 set the crossover between allocations occurring in the @sbrk@ area or separately mapped. 1846 1896 It returns the crossover point used throughout a program, \ie called once at heap initialization. 1847 1897 1848 \medskip\noindent 1849 \lstinline{size_t malloc_unfreed()} 1898 \paragraph{\lstinline{size_t malloc_unfreed()}} 1850 1899 \label{p:malloc_unfreed} 1851 1900 amount subtracted to adjust for unfreed program storage (debug only). 1852 It returns the new subtraction amount and called by @malloc_stats@ (discussed in Section~\ref{}).1901 It returns the new subtraction amount and called by @malloc_stats@. 1853 1902 1854 1903 … … 1857 1906 The following extensions take advantage of overload polymorphism in the \CC type-system. 1858 1907 1859 \medskip\noindent 1860 \lstinline{void * resize( void * oaddr, size_t nalign, size_t size )} 1861 extends @resize@ with an alignment requirement, @nalign@. 1908 \paragraph{\lstinline{void * resize( void * oaddr, size_t nalign, size_t size )}} 1909 extends @resize@ with an alignment re\-quirement. 1910 1911 \noindent\textbf{Usage} 1912 takes three parameters. 1913 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1914 \item 1915 @oaddr@: address to be resized 1916 \item 1917 @nalign@: alignment requirement 1918 \item 1919 @size@: new allocation size (smaller or larger than previous) 1920 \end{itemize} 1862 1921 It returns the address of the old or new storage with the specified new size and alignment, or @NULL@ if @size@ is zero. 1863 1922 1864 \medskip\noindent 1865 \lstinline{void * realloc( void * oaddr, size_t nalign, size_t size )} 1866 extends @realloc@ with an alignment requirement, @nalign@. 1867 It returns the address of the old or new storage with the specified new size and alignment, or @NULL@ if @size@ is zero. 1923 \paragraph{\lstinline{void * realloc( void * oaddr, size_t nalign, size_t size )}} 1924 extends @realloc@ with an alignment re\-quirement and has the same usage as aligned @resize@. 1868 1925 1869 1926 … … 1922 1979 object size: like the \CFA's C-interface, programmers do not have to specify object size or cast allocation results. 1923 1980 \end{itemize} 1924 Note, postfix function call is an alternative call syntax, using backtick @`@, sothe argument appears before the function name, \eg1981 Note, postfix function call is an alternative call syntax, using backtick @`@, where the argument appears before the function name, \eg 1925 1982 \begin{cfa} 1926 1983 duration ?@`@h( int h ); // ? denote the position of the function operand … … 1930 1987 \end{cfa} 1931 1988 1932 The following extensions take advantage of overload polymorphism in the \CC type-system. 1933 1934 \medskip\noindent 1935 \lstinline{T * alloc( ... )} or \lstinline{T * alloc( size_t dim, ... )} 1989 \paragraph{\lstinline{T * alloc( ... )} or \lstinline{T * alloc( size_t dim, ... )}} 1936 1990 is overloaded with a variable number of specific allocation operations, or an integer dimension parameter followed by a variable number of specific allocation operations. 1937 1991 These allocation operations can be passed as named arguments when calling the \lstinline{alloc} routine. … … 1942 1996 1943 1997 The allocation property functions are: 1944 1945 \medskip\noindent 1946 \lstinline{T_align ?`align( size_t alignment )} 1998 \subparagraph{\lstinline{T_align ?`align( size_t alignment )}} 1947 1999 to align the allocation. 1948 The alignment parameter must be $\ge$ the default alignment (@libAlign()@ in \CFA) and a power of two. 1949 The following example returns a dynamic object and object array aligned on a 4096-byte boundary. 2000 The alignment parameter must be $\ge$ the default alignment (@libAlign()@ in \CFA) and a power of two, \eg: 1950 2001 \begin{cfa} 1951 2002 int * i0 = alloc( @4096`align@ ); sout | i0 | nl; … … 1955 2006 0x555555574000 0x555555574000 0x555555574004 0x555555574008 1956 2007 \end{cfa} 1957 1958 \medskip\noindent 1959 \ lstinline{S_fill(T) ?`fill ( /* various types */ )}2008 returns a dynamic object and object array aligned on a 4096-byte boundary. 2009 2010 \subparagraph{\lstinline{S_fill(T) ?`fill ( /* various types */ )}} 1960 2011 to initialize storage. 1961 2012 There are three ways to fill storage: 1962 \begin{enumerate} [itemsep=0pt,parsep=0pt]2013 \begin{enumerate} 1963 2014 \item 1964 2015 A char fills each byte of each object. … … 1969 2020 \end{enumerate} 1970 2021 For example: 1971 \begin{cfa}[numbers=left ,xleftmargin=2.5\parindentlnth]2022 \begin{cfa}[numbers=left] 1972 2023 int * i0 = alloc( @0n`fill@ ); sout | *i0 | nl; // disambiguate 0 1973 2024 int * i1 = alloc( @5`fill@ ); sout | *i1 | nl; … … 1978 2029 int * i6 = alloc( 5, @[i3, 3]`fill@ ); for ( i; 5 ) sout | i6[i]; sout | nl; 1979 2030 \end{cfa} 1980 \begin{lstlisting}[numbers=left ,xleftmargin=2.5\parindentlnth]2031 \begin{lstlisting}[numbers=left] 1981 2032 0 1982 2033 5 … … 1990 2041 Examples 4 to 7 fill an array of objects with values, another array, or part of an array. 1991 2042 1992 \medskip\noindent 1993 \lstinline{S_resize(T) ?`resize( void * oaddr )} 2043 \subparagraph{\lstinline{S_resize(T) ?`resize( void * oaddr )}} 1994 2044 used to resize, realign, and fill, where the old object data is not copied to the new object. 1995 2045 The old object type may be different from the new object type, since the values are not used. 1996 2046 For example: 1997 \begin{cfa}[numbers=left ,xleftmargin=2.5\parindentlnth]2047 \begin{cfa}[numbers=left] 1998 2048 int * i = alloc( @5`fill@ ); sout | i | *i; 1999 2049 i = alloc( @i`resize@, @256`align@, @7`fill@ ); sout | i | *i; 2000 2050 double * d = alloc( @i`resize@, @4096`align@, @13.5`fill@ ); sout | d | *d; 2001 2051 \end{cfa} 2002 \begin{lstlisting}[numbers=left ,xleftmargin=2.5\parindentlnth]2052 \begin{lstlisting}[numbers=left] 2003 2053 0x55555556d5c0 5 2004 2054 0x555555570000 7 … … 2007 2057 Examples 2 to 3 change the alignment, fill, and size for the initial storage of @i@. 2008 2058 2009 \begin{cfa}[numbers=left ,xleftmargin=2.5\parindentlnth]2059 \begin{cfa}[numbers=left] 2010 2060 int * ia = alloc( 5, @5`fill@ ); for ( i; 5 ) sout | ia[i]; sout | nl; 2011 2061 ia = alloc( 10, @ia`resize@, @7`fill@ ); for ( i; 10 ) sout | ia[i]; sout | nl; … … 2013 2063 ia = alloc( 3, @ia`resize@, @4096`align@, @2`fill@ ); sout | ia; for ( i; 3 ) sout | &ia[i] | ia[i]; sout | nl; 2014 2064 \end{cfa} 2015 \begin{lstlisting}[numbers=left ,xleftmargin=2.5\parindentlnth]2065 \begin{lstlisting}[numbers=left] 2016 2066 5 5 5 5 5 2017 2067 7 7 7 7 7 7 7 7 7 7 … … 2021 2071 Examples 2 to 4 change the array size, alignment and fill for the initial storage of @ia@. 2022 2072 2023 \medskip\noindent 2024 \lstinline{S_realloc(T) ?`realloc( T * a ))} 2073 \subparagraph{\lstinline{S_realloc(T) ?`realloc( T * a ))}} 2025 2074 used to resize, realign, and fill, where the old object data is copied to the new object. 2026 2075 The old object type must be the same as the new object type, since the value is used. 2027 2076 Note, for @fill@, only the extra space after copying the data from the old object is filled with the given parameter. 2028 2077 For example: 2029 \begin{cfa}[numbers=left ,xleftmargin=2.5\parindentlnth]2078 \begin{cfa}[numbers=left] 2030 2079 int * i = alloc( @5`fill@ ); sout | i | *i; 2031 2080 i = alloc( @i`realloc@, @256`align@ ); sout | i | *i; 2032 2081 i = alloc( @i`realloc@, @4096`align@, @13`fill@ ); sout | i | *i; 2033 2082 \end{cfa} 2034 \begin{lstlisting}[numbers=left ,xleftmargin=2.5\parindentlnth]2083 \begin{lstlisting}[numbers=left] 2035 2084 0x55555556d5c0 5 2036 2085 0x555555570000 5 … … 2040 2089 The @13`fill@ in example 3 does nothing because no extra space is added. 2041 2090 2042 \begin{cfa}[numbers=left ,xleftmargin=2.5\parindentlnth]2091 \begin{cfa}[numbers=left] 2043 2092 int * ia = alloc( 5, @5`fill@ ); for ( i; 5 ) sout | ia[i]; sout | nl; 2044 2093 ia = alloc( 10, @ia`realloc@, @7`fill@ ); for ( i; 10 ) sout | ia[i]; sout | nl; … … 2046 2095 ia = alloc( 3, @ia`realloc@, @4096`align@, @2`fill@ ); sout | ia; for ( i; 3 ) sout | &ia[i] | ia[i]; sout | nl; 2047 2096 \end{cfa} 2048 \begin{lstlisting}[numbers=left ,xleftmargin=2.5\parindentlnth]2097 \begin{lstlisting}[numbers=left] 2049 2098 5 5 5 5 5 2050 2099 5 5 5 5 5 7 7 7 7 7 -
doc/proposals/enum.tex
r32490deb rc75b30a 7 7 \usepackage{graphics} 8 8 \usepackage{xspace} 9 \usepackage{relsize} % must be after change to small or selects old size10 \usepackage{calc} % latex arithmetic11 9 12 10 \makeatletter … … 24 22 \newcommand{\@newterm}[2][\@empty]{\lowercase{\def\temp{#2}}{\newtermFontInline{#2}}\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi} 25 23 \newcommand{\@snewterm}[2][\@empty]{{\newtermFontInline{#2}}\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi} 26 27 \newcommand{\LstBasicStyle}[1]{{\lst@basicstyle{#1}}}28 \newcommand{\LstKeywordStyle}[1]{{\lst@basicstyle{\lst@keywordstyle{#1}}}}29 \newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}}30 \newcommand{\LstStringStyle}[1]{{\lst@basicstyle{\lst@stringstyle{#1}}}}31 \newcommand{\LstNumberStyle}[1]{{\lst@basicstyle{\lst@numberstyle{#1}}}}32 33 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly34 \newlength{\columnposn}35 \setlength{\gcolumnposn}{3in}36 \setlength{\columnposn}{\gcolumnposn}37 \newcommand{\setgcolumn}[1]{\global\gcolumnposn=#1\global\columnposn=\gcolumnposn}38 \newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\LstCommentStyle{#2}}}39 \newcommand{\CD}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\LstBasicStyle{#2}}}40 \newcommand{\CRT}{\global\columnposn=\gcolumnposn}41 24 \makeatother 42 25 … … 65 48 \newcommand{\CCIcon}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}} % C++ icon 66 49 \newcommand{\CC}[1][]{\protect\CCIcon{#1}\xspace} % C++ symbolic name 67 \newcommand{\Csharp}{C\raisebox{-0.7ex}{\relsize{2}$^\sharp$}\xspace} % C# symbolic name68 50 \newcommand{\PAB}[1]{{\color{red}PAB: #1}} 69 51 … … 74 56 75 57 \lstdefinestyle{CStyle}{ 76 % backgroundcolor=\color{backgroundColour}, 58 % backgroundcolor=\color{backgroundColour}, 77 59 % commentstyle=\color{mGreen}, 78 60 % keywordstyle=\color{magenta}, … … 82 64 basicstyle=\small\linespread{0.9}\sf, % reduce line spacing and use sanserif font 83 65 % basicstyle=\footnotesize, 84 breakatwhitespace=false, 85 % breaklines=true, 86 captionpos=b, 87 keepspaces=true, 66 breakatwhitespace=false, 67 % breaklines=true, 68 captionpos=b, 69 keepspaces=true, 88 70 escapechar=\$, % LaTeX escape in CFA code 89 % numbers=left, 90 % numbersep=5pt, 71 % numbers=left, 72 % numbersep=5pt, 91 73 % numberstyle=\tiny\color{mGray}, 92 % showspaces=false, 74 % showspaces=false, 93 75 showstringspaces=false, 94 % showtabs=false, 76 % showtabs=false, 95 77 showlines=true, % show blank lines at end of code 96 78 tabsize=5, … … 111 93 112 94 \begin{abstract} 113 An enumeration is a type defining an ordered set of named constant values, where a name abstracts a value, e.g., @PI@ versus @3.145159@. 114 C restrict an enumeration type to the integral type @signed int@, which \CC support , meaning enumeration names bind to integer constants. 115 \CFA extends C enumerations to allow all basic and custom types for the enumeration type, like other modern programming languages. 116 Furthermore, \CFA adds other useful features for enumerations to support better software-engineering practices and simplify program development. 95 An enumeration is a type that defines a list of named constant values in C (and other languages). 96 C and \CC use an integral type as the underlying representation of an enumeration. 97 \CFA extends C enumerations to allow all basic and custom types for the inner representation. 117 98 \end{abstract} 118 99 119 \section{Background}120 121 Naming values is a common practice in mathematics and engineering, e.g., $\pi$, $\tau$ (2$\pi$), $\phi$ (golden ratio), MHz (1E6), etc.122 Naming is also commonly used to represent many other numerical phenomenon, such as days of the week, months of a year, floors of a building (basement), time (noon, New Years).123 Many programming languages capture this important capability through a mechanism called an \newterm{enumeration}.124 An enumeration is similar to other programming-language types by providing a set of constrained values, but adds the ability to name \emph{all} the values in its set.125 Note, all enumeration names must be unique but different names can represent the same value (eight note, quaver), which are synonyms.126 127 Specifically, an enumerated type is a type whose values are restricted to a fixed set of named constants.128 Fundamentally, all types are restricted to a fixed set of values because of the underlying von Neumann architecture, and hence, to a corresponding set of constants, e.g., @3@, @3.5@, @3.5+2.1i@, @'c'@, @"abc"@, etc.129 However, the values for basic types are not named, other than the programming-language supplied constants.130 131 132 100 \section{C-Style Enum} 133 101 134 The C-Style enumeration has the followingsyntax and semantics.102 \CFA supports the C-Style enumeration using the same syntax and semantics. 135 103 \begin{lstlisting}[label=lst:weekday] 136 enum Weekday { Monday, Tuesday, Wednesday, Thursday @ = 10@, Friday, Saturday, Sunday };137 $\(\uparrow\)$ $\(\uparrow\)$138 ${\rm \newterm{enumeration name}}$ ${\rm \newterm{enumerator names}}139 \end{lstlisting} 140 Here, the enumeration type @Weekday@ defines the ordered \newterm{enumerator}s @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@.104 enum Weekday { Monday, Tuesday, Wednesday, Thursday=10, Friday, Saturday, Sunday }; 105 $\(\uparrow\)$ $\(\uparrow\)$ 106 ${\rm \newterm{enumeration name}}$ ${\rm \newterm{enumerator names}} 107 \end{lstlisting} 108 The example defines an enumeration type @Weekday@ with ordered enumerators @Monday@, @Tuesday@, @Wednesday@, @Thursday@, @Friday@, @Saturday@ and @Sunday@. 141 109 The successor of @Tuesday@ is @Monday@ and the predecessor of @Tuesday@ is @Wednesday@. 142 A C enumeration is implemented by an integral type, with consecutive enumerator values assigned by the compiler starting at zero or the next explicitly initialized value.143 For example, @Monday@ to @Wednesday@ have values 0--2 implicitly set by the compiler, @Thursday@ is explicitly set to @10@ , and @Friday@ to @Sunday@ have values 11--13 implicitly set by the compiler.110 A C enumeration is an integral type, with consecutive enumerator values assigned by the compiler starting at zero or the next explicitly initialized value by the programmer. 111 For example, @Monday@ to @Wednesday@ have values 0--2 implicitly set by the compiler, @Thursday@ is explicitly set to @10@ by the programmer, and @Friday@ to @Sunday@ have values 11--13 implicitly set by the compiler. 144 112 145 113 There are 3 attributes for an enumeration: \newterm{position}, \newterm{label}, and \newterm{value}: … … 150 118 \it position & 0 & 1 & 2 & 3 & 4 & 5 & 6 \\ 151 119 \it label & Monday & Tuesday & Wednesday & Thursday & Friday & Saturday & Sunday \\ 152 \it value & 0 & 1 & 2 & {\color{red}10}& 11 & 12 & 13120 \it value & 0 & 1 & 2 & 10 & 11 & 12 & 13 153 121 \end{tabular} 154 122 \end{cquote} 155 123 156 124 The enumerators of an enumeration are unscoped, i.e., enumerators declared inside of an @enum@ are visible in the enclosing scope of the @enum@ type. 157 Furthermore, there is an implicit bidirectional conversion between an enumeration and integral types.158 125 \begin{lstlisting}[label=lst:enum_scope] 159 126 { 160 enum Weekday { ... }; $\C{// enumerators implicitly projected into local scope}$127 enum Weekday { ... }; // enumerators implicitly projected into local scope 161 128 Weekday weekday = Monday; 162 weekday = Friday; $\C{// weekday == 11}$ 163 int i = Sunday $\C{// i == 13}$ 164 weekday = 10000; $\C{// undefined behaviour}$ 129 weekday = Friday; 130 int i = Sunday // i == 13 165 131 } 166 int j = Wednesday; $\C{// ERROR! Wednesday is not declared in this scope}$132 int j = Wednesday; // ERROR! Wednesday is not declared in this scope 167 133 \end{lstlisting} 168 134 169 135 \section{\CFA-Style Enum} 170 136 171 \CFA supports C-Style enumeration using the same syntax and semantics for backwards compatibility. 172 \CFA also extends C-Style enumeration by adding a number of new features that bring enumerations inline with other modern programming languages. 173 174 \subsection{Enumerator Typing} 175 176 \CFA extends the enumeration by parameterizing the enumeration with a type for the enumerators, allowing enumerators to be assigned any values from the declared type. 137 A \CFA enumeration is parameterized by a type specifying each enumerator's type. 138 \CFA allows any object type for the enumerators, and values assigned to enumerators must be from the declared type. 177 139 \begin{lstlisting}[label=lst:color] 178 enum( @char@ ) Currency { Dollar = '$\textdollar$', Euro = '$\texteuro$', Pound = '$\textsterling$' }; 179 enum( @double@ ) Planet { Venus = 4.87, Earth = 5.97, Mars = 0.642 }; // mass 180 enum( @char *@ ) Colour { Red = "red", Green = "green", Blue = "blue" }; 181 enum( @Currency@ ) Europe { Euro = '$\texteuro$', Pound = '$\textsterling$' }; // intersection 182 \end{lstlisting} 183 The types of the enumerators are @char@, @double@, and @char *@ and each enumerator is initialized with corresponding type values. 184 % Only types with a defined ordering can be automatically initialized (see Section~\ref{s:AutoInitializable}). 140 enum Colour( @char *@ ) { Red = "R", Green = "G", Blue = "B" }; 141 \end{lstlisting} 142 The type of @Colour@ is @char *@ and each enumerator is initialized with a C string. 143 Only types with a defined ordering can be automatically initialized (see Section~\ref{s:AutoInitializable}). 185 144 186 145 % An instance of \CFA-enum (denoted as @<enum_instance>@) is a label for the defined enum name. … … 192 151 A \CFA-enum can be scoped, meaning the enumerator constants are not projected into the enclosing scope. 193 152 \begin{lstlisting} 194 enum Weekday @!@ { /* as above */ }; 195 enum Colour( char * ) @!@ { /* as above */ }; 153 enum Colour( char * ) @!@ { ... }; 196 154 \end{lstlisting} 197 155 where the @'!'@ implies the enumerators are \emph{not} projected. … … 200 158 % $$<qualified\_expression> := <enum\_type>.<enumerator>$$ 201 159 \begin{lstlisting} 202 Weekday weekday = @Weekday.Monday@; $\C{// qualification}$ 203 Colour colour = @Colour.@Red; 160 Colour colour = @Colour.@Red; // qualification 204 161 colour = @Colour.@Blue; 205 162 \end{lstlisting} 206 163 207 \subsection{Enumeration Pseudo-functions} 208 209 Pseudo-functions are function-like operators that do not result in any run-time computations, i.e., like @sizeof@. 210 Often a call to a pseudo-function is substituted with information extracted from the symbol table at compilation time, like storage size or alignment associated with the underlying architecture.. 211 212 \subsubsection{Enumerator Attributes} 213 The attributes of an enumerator are accessed by pseudo-functions @position@, @value@, and @label@. 164 \section{Enumeration Pseudo-functions} 165 Pseudo-functions are function-like operators that do not result in any run-time computations, i.e., like @sizeof@. Instead, the call to functions will be substituted into other expressions in compilation time. 166 167 \subsection{Enumerator Attributes} 168 The attributes of an enumerator are accessed by pseudo-functions @position@, @value@, and @label@. 214 169 \begin{lstlisting} 215 int green_pos = @position@( Colour.Green ); $\C{// 1}$ 216 char * green_value = @value@( Colour.Green ); $\C{// "G"}$ 217 char * green_label = @label@( Colour.Green ); $\C{// "Green"}$ 218 \end{lstlisting} 219 220 Enumeration Greek may have more or less enumerators than Letter, but the enumerator values must be from Letter. 221 Therefore, Greek enumerators are a subset of type Letter and are type compatible with enumeration Letter, but Letter enumerators are not type compatible with enumeration Greek. 222 223 \subsubsection{\lstinline{enumerate()}} 224 170 int green_pos = @position@( Colour.Green ); // 1 171 char * green_value = @value@( Colour.Green ); / "G" 172 char * green_label = @label@( Colour.Green ); // "Green" 173 \end{lstlisting} 174 175 \subsection{enumerate()} 225 176 \begin{lstlisting}[label=lst:c_switch] 226 177 enum(int) C_ENUM { First, Second, Third = First, Fourth }; 227 int v( C_ENUM e ) { 228 switch( e ) { 229 case First: return 0; break; 230 case Second: return 1; break; 231 // case Third: return 2; break; 232 // case Fourth: return 3; break; 233 }; 234 }; 235 \end{lstlisting} 236 In the @C_ENUM@ example, @Third@ is an alias of @First@ and @Fourth@ is an alias of @Second@. 237 Programmers cannot make case branches for @Third@ and @Fourth@ because the switch statement matches cases by the enumerator's value. 238 Case @First@ and @Third@, or @Second@ and @Fourth@, has duplicate case values. 239 240 @enumerate()@ is a pseudo-function that makes the switch statement match by an enumerator instead. 178 int v(C_ENUM e) { 179 switch( e ) { 180 case First: return 0; break; 181 case Second: return 1; break; 182 // case Thrid: return 2; break; 183 // case Fourth: return 3; break; 184 }; 185 }; 186 \end{lstlisting} 187 In the @C_ENUM@ example, @Third@ is an alias of @First@ and @Fourth@ is an alias of @Second@. Programmers cannot make case branches for @Third@ and @Fourth@ because the switch statement matches cases by the enumerator's value. Case First and Third, or Second and Fourth, has duplicate case values. 188 189 @enumerate()@ is a pseudo-function that makes the switch statement match by an enumerator instead. 241 190 \begin{lstlisting}[label=lst:c_switch_enumerate] 242 191 enum(double) C_ENUM { First, Second, Third = First, Fourth }; 243 C_ENUM variable_a = First, variable_b = Second, variable_c = Th ird, variable_d = Fourth;244 int v(C_ENUM e) { 245 switch( enumeratate( e ) ) {246 case First: return e; break;247 case Second: return value( e ); break;248 case Third: return label( e ); break;249 case Fourth: return position( e ); break;250 };192 C_ENUM variable_a = First, variable_b = Second, variable_c = Thrid, variable_d = Fourth; 193 int v(C_ENUM e) { 194 switch( enumeratate( e ) ) { 195 case First: return e; break; 196 case Second: return value( e ); break; 197 case Thrid: return label( e ); break; 198 case Fourth: return position( e ); break; 199 }; 251 200 }; 252 201 p(variable_a); // 0 … … 256 205 \end{lstlisting} 257 206 258 259 207 \section{Enumeration Storage} 260 261 208 262 209 \subsection{Enumeration Variable} … … 281 228 >>> label( Colour, 1) -> char * 282 229 \end{lstlisting} 283 @T@ represents the type declared in the \CFA enumeration defined and @char *@ in the example. 230 @T@ represents the type declared in the \CFA enumeration defined and @char *@ in the example. 284 231 These generated functions are $Companion Functions$, they take an $companion$ object and the position as parameters. 285 232 286 287 233 \subsection{Enumeration Data} 288 289 234 \begin{lstlisting}[label=lst:enumeration_backing_data] 290 235 enum(T) E { ... }; 291 236 // backing data 292 T * E_values; 293 char ** E_labels; 294 \end{lstlisting} 295 Storing values and labels as arrays can sometimes help support enumeration features. 296 However, the data structures are the overhead for the programs. We want to reduce the memory usage for enumeration support by: 237 T* E_values; 238 char** E_labels; 239 \end{lstlisting} 240 Storing values and labels as arrays can sometimes help support enumeration features. However, the data structures are the overhead for the programs. We want to reduce the memory usage for enumeration support by: 297 241 \begin{itemize} 298 \item Only generates the data array if necessary 299 \item The compilation units share the data structures. 300 No extra overhead if the data structures are requested multiple times. 242 \item Only generates the data array if necessary 243 \item The compilation units share the data structures. No extra overhead if the data structures are requested multiple times. 301 244 \end{itemize} 302 245 303 246 247 \ 304 248 \section{Unification} 305 249 306 250 \subsection{Enumeration as Value} 307 251 \label{section:enumeration_as_value} 308 An \CFA enumeration with base type T can be used seamlessly as T, without explicitly calling the pseudo-function value. 252 An \CFA enumeration with base type T can be used seamlessly as T, without explicitly calling the pseudo-function value. 309 253 \begin{lstlisting}[label=lst:implicit_conversion] 310 254 char * green_value = Colour.Green; // "G" 311 // Is equivalent to 255 // Is equivalent to 312 256 // char * green_value = value( Color.Green ); "G" 313 257 \end{lstlisting} 314 258 315 316 259 \subsection{Unification Distance} 317 318 260 \begin{lstlisting}[label=lst:unification_distance_example] 319 261 T_2 Foo(T1); … … 323 265 @path(A, B)@ is a compiler concept that returns one of the following: 324 266 \begin{itemize} 325 \item Zero or 0, if and only if $A == B$.326 \item Safe, if B can be used as A without losing its precision, or B is a subtype of A. 327 \item Unsafe, if B loses its precision when used as A, or A is a subtype of B.328 \item Infinite, if B cannot be used as A. A is not a subtype of B and B is not a subtype of A.267 \item Zero or 0, if and only if $A == B$. 268 \item Safe, if B can be used as A without losing its precision, or B is a subtype of A. 269 \item Unsafe, if B loses its precision when used as A, or A is a subtype of B. 270 \item Infinite, if B cannot be used as A. A is not a subtype of B and B is not a subtype of A. 329 271 \end{itemize} 330 272 … … 336 278 The arithmetic of distance is the following: 337 279 \begin{itemize} 338 \item $Zero + v= v$, for some value v.339 \item $Safe * k < Unsafe$, for finite k. 340 \item $Unsafe * k < Infinite$, for finite k.341 \item $Infinite + v = Infinite$, for some value v.280 \item $Zero + v= v$, for some value v. 281 \item $Safe * k < Unsafe$, for finite k. 282 \item $Unsafe * k < Infinite$, for finite k. 283 \item $Infinite + v = Infinite$, for some value v. 342 284 \end{itemize} 343 285 … … 346 288 347 289 \subsection{Variable Overloading and Parameter Unification} 348 349 290 \CFA allows variable names to be overloaded. It is possible to overload a variable that has type T and an enumeration with type T. 350 291 \begin{lstlisting}[label=lst:variable_overload] … … 363 304 Similarly, functions can be overloaded with different signatures. \CFA picks the correct function entity based on the distance between parameter types and the arguments. 364 305 \begin{lstlisting}[label=lst:function_overload] 365 Colour green = Colour.Green; 306 Colour green = Colour.Green; 366 307 void foo(Colour c) { sout | "It is an enum"; } // First foo 367 308 void foo(char * s) { sout | "It is a string"; } // Second foo … … 385 326 % The @EnumInstType@ is convertible to other types. 386 327 % A \CFA enumeration expression is implicitly \emph{overloaded} with its three different attributes: value, position, and label. 387 % The \CFA compilers need to resolve an @EnumInstType@ as one of its attributes based on the current context. 328 % The \CFA compilers need to resolve an @EnumInstType@ as one of its attributes based on the current context. 388 329 389 330 % \begin{lstlisting}[caption={Null Context}, label=lst:null_context] … … 438 379 % } 439 380 % \end{lstlisting} 440 % % The conversion can work backward: in restrictive cases, attributes of can be implicitly converted back to the EnumInstType. 381 % % The conversion can work backward: in restrictive cases, attributes of can be implicitly converted back to the EnumInstType. 441 382 % Backward conversion: 442 383 % \begin{lstlisting}[caption={Unification Functions}, label=lst:unification_func_call] … … 448 389 % \begin{lstlisting}[caption={Unification Functions}, label=lst:unification_func_call] 449 390 % { 450 % Unification( EnumInstType<Colour>, int ) >>> label391 % Unification( EnumInstType<Colour>, int ) >>> label 451 392 % } 452 393 % \end{lstlisting} 453 394 % @int@ can be unified with the label of Colour. 454 % @5@ is a constant expression $\Rightarrow$ Compiler knows the value during the compilation $\Rightarrow$ turns it into 395 % @5@ is a constant expression $\Rightarrow$ Compiler knows the value during the compilation $\Rightarrow$ turns it into 455 396 % \begin{lstlisting} 456 397 % { 457 % enum Colour colour = Colour.Green;398 % enum Colour colour = Colour.Green; 458 399 % } 459 400 % \end{lstlisting} … … 470 411 % { 471 412 % enum T (int) { ... } // Declaration 472 % enum T t = 1; 413 % enum T t = 1; 473 414 % } 474 415 % \end{lstlisting} … … 482 423 % return the FIRST enumeration constant that has the value 1, by searching through the values array 483 424 % \end{enumerate} 484 % The downside of the precedence rule: @EnumInstType@ $\Rightarrow$ @int ( value )@ $\Rightarrow$ @EnumInstType@ may return a different @EnumInstType@ because the value can be repeated and there is no way to know which one is expected $\Rightarrow$ want uniqueness 425 % The downside of the precedence rule: @EnumInstType@ $\Rightarrow$ @int ( value )@ $\Rightarrow$ @EnumInstType@ may return a different @EnumInstType@ because the value can be repeated and there is no way to know which one is expected $\Rightarrow$ want uniqueness 485 426 486 427 % \subsection{Casting} … … 490 431 % (int) Foo.A; 491 432 % \end{lstlisting} 492 % The \CFA-compiler unifies @EnumInstType<int>@ with int, with returns @value( Foo.A )@, which has statically known value 10. In other words, \CFA-compiler is aware of a cast expression, and it forms the context for EnumInstType resolution. The expression with type @EnumInstType<int>@ can be replaced by the compile with a constant expression 10, and optionally discard the cast expression. 433 % The \CFA-compiler unifies @EnumInstType<int>@ with int, with returns @value( Foo.A )@, which has statically known value 10. In other words, \CFA-compiler is aware of a cast expression, and it forms the context for EnumInstType resolution. The expression with type @EnumInstType<int>@ can be replaced by the compile with a constant expression 10, and optionally discard the cast expression. 493 434 494 435 % \subsection{Value Conversion} … … 504 445 % int j = value( Foo, a ) 505 446 % \end{lstlisting} 506 % Similarly, the generated code for the third line is 447 % Similarly, the generated code for the third line is 507 448 % \begin{lstlisting} 508 449 % char * j = label( Foo, a ) … … 514 455 515 456 \subsection{C Enumeration Rule} 516 A C enumeration has an integral type. If not initialized, the first enumerator implicitly has the integral value 0, and other enumerators have a value equal to its $predecessor + 1$. 457 A C enumeration has an integral type. If not initialized, the first enumerator implicitly has the integral value 0, and other enumerators have a value equal to its $predecessor + 1$. 517 458 518 459 \subsection{Auto Initializable} … … 537 478 Odd ?++( Odd t1 ) { return Odd( t1.i + 2); }; 538 479 \end{lstlisting} 539 When the type of an enumeration is @AutoInitializable@, implicit initialization is available. 480 When the type of an enumeration is @AutoInitializable@, implicit initialization is available. 540 481 \begin{lstlisting}[label=lst:sample_auto_Initializable_usage] 541 482 enum AutoInitUsage(Odd) { … … 573 514 @alph@ is the iterating enumeration object, which returns the value of an @Alphabet@ in this context according to the precedence rule. 574 515 575 \textbullet\ \CFA offers a shorthand for iterating all enumeration constants: 516 \textbullet\ \CFA offers a shorthand for iterating all enumeration constants: 576 517 \begin{lstlisting}[label=lst:range_functions] 577 518 for ( Alphabet alph ) { sout | alph; } … … 626 567 >>> 10 11 12 13 14 15 16 17 18 627 568 \end{lstlisting} 628 The first syntax is stepping to the next enumeration constant, which is the default stepping scheme if not explicitly specified. The second syntax, on the other hand, is to call @operator+=@ @one_type@ on the @value( s )@. Therefore, the second syntax is equivalent to 569 The first syntax is stepping to the next enumeration constant, which is the default stepping scheme if not explicitly specified. The second syntax, on the other hand, is to call @operator+=@ @one_type@ on the @value( s )@. Therefore, the second syntax is equivalent to 629 570 \begin{lstlisting}[label=lst:range_function_stepping_converted] 630 571 for ( typeof( value(Sequence.A) ) s=value( Sequence.A ); s <= Sequence.D; s+=1 ) { sout | alph; } … … 638 579 for ( char * alph; Alphabet ) 639 580 \end{lstlisting} 640 This for-loop implicitly iterates every label of the enumeration, because a label is the only valid resolution to @ch@with type @char *@ in this case.581 This for-loop implicitly iterates every label of the enumeration, because a label is the only valid resolution to the ch with type @char *@ in this case. 641 582 If the value can also be resolved as the @char *@, you might iterate the labels explicitly with the array iteration. 642 583 \begin{lstlisting}[label=lst:range_functions_label_implicit] … … 650 591 % \begin{lstlisting} 651 592 % enum T( int, char * ) { 652 % a=42, b="Hello World"593 % a=42, b="Hello World" 653 594 % }; 654 595 % \end{lstlisting} 655 % The enum T declares two different types: int and char *. The enumerators of T hold values of one of the declared types. 596 % The enum T declares two different types: int and char *. The enumerators of T hold values of one of the declared types. 656 597 657 598 \subsection{Enumeration Inheritance} … … 661 602 enum /* inferred */ Name2 { inline Name, Sue = "Sue", Tom = "Tom" }; 662 603 \end{lstlisting} 663 \lstinline{Inline} allows Enumeration Name2 to inherit enumerators from Name1 by containment, and a Name enumeration is a subtype of enumeration Name2. An enumeration instance of type Name can be used where an instance of Name2 is expected. 604 \lstinline{Inline} allows Enumeration Name2 to inherit enumerators from Name1 by containment, and a Name enumeration is a subtype of enumeration Name2. An enumeration instance of type Name can be used where an instance of Name2 is expected. 664 605 \begin{lstlisting}[label=lst:EnumInline] 665 606 Name Fred; … … 669 610 If enumeration A declares @inline B@ in its enumeration body, enumeration A is the "inlining enum" and enumeration B is the "inlined enum". 670 611 671 An enumeration can inline at most one other enumeration. The inline declaration must be placed before the first enumerator of the inlining enum. The inlining enum has all the enumerators from the inlined enum, with the same labels, values, and position. 612 An enumeration can inline at most one other enumeration. The inline declaration must be placed before the first enumerator of the inlining enum. The inlining enum has all the enumerators from the inlined enum, with the same labels, values, and position. 672 613 \begin{lstlisting}[label=lst:EnumInline] 673 614 enum /* inferred */ Name2 { inline Name, Sue = "Sue", Tom = "Tom" }; … … 684 625 \begin{lstlisting}[label=lst:static_attr] 685 626 enum( char * ) Colour { 686 Red = "red", Blue = "blue", Green = "green" 687 }; 688 \end{lstlisting} 689 An enumerator expression returns its enumerator value as a constant expression with no runtime cost. For example, @Colour.Red@ is equivalent to the constant expression "red", and \CFA finishes the expression evaluation before generating the corresponding C code. Applying a pseudo-function to a constant enumerator expression results in a constant expression as well. @value( Colour.Red )@, @position( Colour. Red )@, and @label( Colour.Red )@ are equivalent to constant expression with char * value "red", int value 0, and char * value "Red", respectively. 627 Red = "red", Blue = "blue", Green = "green" 628 }; 629 \end{lstlisting} 630 An enumerator expression returns its enumerator value as a constant expression with no runtime cost. For example, @Colour.Red@ is equivalent to the constant expression "red", and \CFA finishes the expression evaluation before generating the corresponding C code. Applying a pseudo-function to a constant enumerator expression results in a constant expression as well. @value( Colour.Red )@, @position( Colour. Red )@, and @label( Colour.Red )@ are equivalent to constant expression with char * value "red", int value 0, and char * value "Red", respectively. 690 631 691 632 \subsection{Runtime Attribute Expression and Weak Referenced Data} … … 697 638 An enumeration variable c is equivalent to an integer variable with the value of @position( c )@ In Example~\ref{lst:dynamic_attr}, the value of enumeration variable c is unknown at compile time. In this case, the pseudo-function calls are reduced to expression that returns the enumerator values at runtime. 698 639 699 \CFA stores the variables and labels in @const@ arrays to provide runtime lookup for enumeration information.640 \CFA stores the variables and labels in const arrays to provide runtime lookup for enumeration information. 700 641 701 642 \begin{lstlisting}[label=lst:attr_array] … … 710 651 \end{lstlisting} 711 652 712 To avoid unnecessary memory usage, the labels and values array are only generated as needed, and only generate once across all compilation units. By default, \CFA defers the declaration of the label and value arrays until an call to attribute function with a dynamic value. If an attribute function is never called on a dynamic value of an enumerator, the array will never be allocated. Once the arrays are created, all compilation units share a weak reference to the allocation array. 653 To avoid unnecessary memory usage, the labels and values array are only generated as needed, and only generate once across all compilation units. By default, \CFA defers the declaration of the label and value arrays until an call to attribute function with a dynamic value. If an attribute function is never called on a dynamic value of an enumerator, the array will never be allocated. Once the arrays are created, all compilation units share a weak reference to the allocation array. 713 654 714 655 \subsection{Enum Prelude} … … 716 657 \begin{lstlisting}[label=lst:enum_func_dec] 717 658 forall( T ) { 718 unsigned position( unsigned );719 T value( unsigned );720 char * label( unsigned );659 unsigned position( unsigned ); 660 T value( unsigned ); 661 char * label( unsigned ); 721 662 } 722 663 \end{lstlisting} … … 729 670 forall(T) 730 671 class EnumDecl { 731 T* values;732 char** label;672 T* values; 673 char** label; 733 674 }; 734 675 \end{lstlisting} … … 738 679 \begin{lstlisting}[label=lst:EnumInstType] 739 680 class EnumInstType { 740 EnumDecl enumDecl;741 int position;681 EnumDecl enumDecl; 682 int position; 742 683 }; 743 684 \end{lstlisting} … … 759 700 % struct Companion { 760 701 % const T * const values; 761 % const char * label;702 % const char * label; 762 703 % int length; 763 704 % }; … … 765 706 % \CFA generates companion objects, an instance of structure that encloses @necessary@ data to represent an enumeration. The size of the companion is unknown at the compilation time, and it "grows" in size to compensate for the @usage@. 766 707 767 % The companion object is singleton across the compilation (investigation). 708 % The companion object is singleton across the compilation (investigation). 768 709 769 710 % \CFA generates the definition of companion functions. … … 786 727 \begin{lstlisting}[label=lst:companion_trait] 787 728 forall(T1) { 788 trait Companion(otype T2<otype T1>) {789 T1 value((otype T2<otype T1> const &);790 int position(otype T2<otype T1> const &);791 char * label(otype T2<otype T1> const &);792 }729 trait Companion(otype T2<otype T1>) { 730 T1 value((otype T2<otype T1> const &); 731 int position(otype T2<otype T1> const &); 732 char * label(otype T2<otype T1> const &); 733 } 793 734 } 794 735 \end{lstlisting} … … 802 743 \begin{lstlisting} 803 744 enum(int) Weekday { 804 Monday=10, Tuesday, ...745 Monday=10, Tuesday, ... 805 746 }; 806 747 … … 817 758 \subsection{User Define Enumeration Functions} 818 759 819 Companion objects make extending features for \CFA enumeration easy. 760 Companion objects make extending features for \CFA enumeration easy. 820 761 \begin{lstlisting}[label=lst:companion_user_definition] 821 char * charastic_string( Companion o, int position ) { 822 return sprintf( "Label: %s; Value: %s", label( o, position ), value( o, position) ); 762 char * charastic_string( Companion o, int position ) { 763 return sprintf( "Label: %s; Value: %s", label( o, position ), value( o, position) ); 823 764 } 824 765 printf( charactic_string ( Color, 1 ) ); … … 835 776 Similarly, the user can work with the enumeration type itself: (see section ref...) 836 777 \begin{lstlisting}[ label=lst:companion_user_definition] 837 void print_enumerators ( Companion o ) { 778 void print_enumerators ( Companion o ) { 838 779 for ( c : Companion o ) { 839 780 sout | label (c) | value( c ) ; 840 } 781 } 841 782 } 842 783 print_enumerators( Colour ); … … 854 795 It ensures that the name of an enumerator is unique within the enumeration body, and checks if all values of the enumerator have the declaration type. 855 796 If the declared type is not @AutoInitializable@, \CFA rejects the enumeration definition. 856 Otherwise, it attempts to initialize enumerators with the enumeration initialization pattern. (a reference to a future initialization pattern section) 797 Otherwise, it attempts to initialize enumerators with the enumeration initialization pattern. (a reference to a future initialization pattern section) 857 798 858 799 \begin{lstlisting}[label=lst:init] … … 862 803 T ?+?( T & lhs, T & rhs ) { ... }; 863 804 864 enum (T) Sample { 865 Zero: 0 /* zero_t */, 805 enum (T) Sample { 806 Zero: 0 /* zero_t */, 866 807 One: Zero + 1 /* ?+?( Zero, one_t ) */ , ... 867 808 }; … … 885 826 \subsection{Qualified Expression} 886 827 887 \CFA uses qualified expression to address the scoping of \CFA-enumeration. 828 \CFA uses qualified expression to address the scoping of \CFA-enumeration. 888 829 \begin{lstlisting}[label=lst:qualified_expression] 889 830 aggregation_name.field; … … 896 837 897 838 \subsection{\lstinline{with} Clause/Statement} 898 899 839 Instead of qualifying an enumeration expression every time, the @with@ can be used to expose enumerators to the current scope, making them directly accessible. 900 840 \begin{lstlisting}[label=lst:declaration] … … 902 842 enum Animal( int ) { Cat=10, Dog=20 }; 903 843 with ( Color, Animal ) { 904 char * red_string = Red; // value( Color.Red )905 int cat = Cat; // value( Animal.Cat )844 char * red_string = Red; // value( Color.Red ) 845 int cat = Cat; // value( Animal.Cat ) 906 846 } 907 847 \end{lstlisting} … … 911 851 enum RGB( int ) { Red=0, Green=1, Blue=2 }; 912 852 with ( Color, RGB ) { 913 // int red = Red; 853 // int red = Red; 914 854 } 915 855 \end{lstlisting} … … 925 865 The declaration \CFA-enumeration variable has the same syntax as the C-enumeration. Internally, such a variable will be represented as an EnumInstType. 926 866 927 \section{Related Work}928 929 Enumerations exist in many popular programming languages, e.g., Pascal, Ada, \Csharp, \CC, Go, Java, Modula-3, Rust, Swift, Python, and Algebraic data type in functional programming.930 There are a large set of overlapping features for all the languages, but each language has its own unique restrictions and extensions.931 932 \subsection{Pascal}933 934 \subsection{Ada}935 936 \subsection{\Csharp}937 938 \subsection{\CC}939 940 Because \CC is backwards compatible with C, it inherited C's enumerations, except there is no implicit conversion from an integral value to an enumeration;941 hence, the values in a \CC enumeration can only be its enumerators.942 943 \CC{11} extended enumeration with a scoped enumeration, \lstinline[language=c++]{enum class} (or \lstinline[language=c++]{enum struct}), where the enumerators are local to the enumeration and are accessed using type qualification, e.g., @Weekday::Monday@.944 \CC{20} supports unscoped access with a \lstinline[language=c++]{using enum} declaration.945 946 For both unscoped and scoped enumerations, the underlying type is an implementation-defined integral type that is large enough to hold all enumerated values; it does not have to be the smallest possible type.947 The underlying integral type can be explicitly specified:948 \begin{lstlisting}[language=c++,{moredelim=**[is][\color{red}]{@}{@}}]949 enum class RGB : @long@ { Red, Green, Blue };950 enum class rgb : @char@ { Red = 'r', Green = 'g', Blue = 'b' };951 enum class srgb : @signed char@ { Red = -1, Green = 0, Blue = 1 };952 \end{lstlisting}953 954 \subsection{Go}955 956 \subsection{Java}957 958 \subsection{Modula-3}959 960 \subsection{Rust}961 962 \subsection{Swift}963 964 \subsection{Python}965 966 \subsection{Algebraic Data Type}967 867 968 868 \end{document} -
doc/uC++toCFA/Makefile
r32490deb rc75b30a 8 8 BibTeX = BIBINPUTS=../bibliography: && export BIBINPUTS && bibtex 9 9 10 MAKEFLAGS = --no-print-directory # --silent10 MAKEFLAGS = --no-print-directory --silent # 11 11 VPATH = ${Build} ${Figures} 12 12 -
doc/uC++toCFA/uC++toCFA.tex
r32490deb rc75b30a 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Thu Jan 11 14:46:14 202414 %% Update Count : 59 4213 %% Last Modified On : Sun Oct 15 23:09:58 2023 14 %% Update Count : 5926 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 428 428 \begin{uC++} 429 429 struct S { 430 int i = 0; // cheat, implicit default constructor430 int i = 0; 431 431 int setter( int j ) { int t = i; i = j; return t; } 432 432 int getter() { return i; } … … 434 434 435 435 S s; 436 @s.@setter( 3 ); // object-oriented call s436 @s.@setter( 3 ); // object-oriented call 437 437 int k = @s.@getter(); 438 438 \end{uC++} … … 442 442 int i; 443 443 }; 444 void ?{}( S & s ) { s.i = 0; } // explicit default constructor444 void ?{}( S & s ) { s.i = 0; } 445 445 int setter( @S & s,@ int j ) @with(s)@ { int t = i; i = j; return t; } 446 446 int getter( @S & s@ ) @with(s)@ { return i; } 447 447 S s; 448 setter( @s,@ 3 ); // normal routine call s448 setter( @s,@ 3 ); // normal routine call 449 449 int k = getter( @s@ ); 450 450 \end{cfa} … … 458 458 \begin{tabular}{l|l} 459 459 \begin{uC++} 460 461 460 struct S { 462 461 int i; 463 S( int i ) { S::i = i; cout << "ctor " <<S::i << endl; }464 ~S() { S::i = i; cout << "dtor " << S::i << endl; } 465 };462 S( int i ) { S::i = i; cout << S::i << endl; } 463 }; 464 @uNoCtor<S>@ s[10]; 466 465 int main() { 467 enum { N = 5 }; 468 @uNoCtor<S>@ s[N]; // no constructor calls 469 for ( int i = 0; i < N; i += 1 ) @s[i].ctor( i )@; 470 for ( int i = 0; i < N; i += 1 ) cout << s[i]@->@i << endl; 471 } 472 \end{uC++} 473 & 474 \begin{cfa} 475 #include @<raii.hfa>@ // uninit 466 for ( int i = 0; i < 10; i += 1 ) { 467 s[i].ctor( i ); 468 } 469 for ( int i = 0; i < 10; i += 1 ) { 470 cout << s[i]@->@i << endl; 471 } 472 } 473 \end{uC++} 474 & 475 \begin{cfa} 476 476 struct S { 477 477 int i; 478 478 }; 479 void ?{}( S & s, int i ) { s.i = i; sout | "ctor" |s.i; }480 void ^?{}( S & s ) { sout | "dtor" | s.i; } 479 void ?{}( S & s, int i ) { s.i = i; sout | s.i; } 480 S s[10] @$\color{red}@$= {}@; 481 481 int main() { 482 enum { N = 5 }; 483 @uninit(S)@ s[N]; // no constructor calls 484 for ( i; N ) @s[i]{ i }@; 485 for ( i; N ) sout | s[i]@.@i; 482 for ( i; 10 ) { 483 ?{}( s[i], i ); // call constructor 484 } 485 for ( i; 10 ) { 486 sout | s[i]@.@i; // dot not arrow 487 } 486 488 } 487 489 \end{cfa} -
doc/user/user.tex
r32490deb rc75b30a 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Tue Jan 30 09:02:41 202414 %% Update Count : 604613 %% Last Modified On : Sun Jan 14 17:27:41 2024 14 %% Update Count : 5764 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 46 46 %\input{common} % common CFA document macros 47 47 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref} 48 \urlstyle{sf}49 48 \usepackage{breakurl} 50 49 … … 164 163 165 164 \Index*[C++]{\CC{}}~\cite{c++:v1} had a similar goal 30 years ago, allowing object-oriented programming to be incrementally added to C. 166 However, \CC currently has the disadvantages of a strong object-oriented bias, multiple legacy design-choices that are difficult to update, and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C code-base.165 However, \CC currently has the disadvantages of a strong object-oriented bias, multiple legacy design-choices that are difficult to update, and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project. 167 166 In contrast, \CFA has 30 years of hindsight and a clean starting point. 168 167 … … 201 200 \end{center} 202 201 While \CFA I/O \see{\VRef{s:StreamIOLibrary}} looks similar to \Index*[C++]{\CC{}}, there are important differences, such as automatic spacing between variables and an implicit newline at the end of the expression list, similar to \Index*{Python}~\cite{Python}. 203 In general, \CFA programs are 10\% to 30\% shorter than their equivalent C/\CC counterparts.204 202 205 203 … … 220 218 Even with all its problems, C continues to be popular because it allows writing software at virtually any level in a computer system without restriction. 221 219 For system programming, where direct access to hardware, storage management, and real-time issues are a requirement, C is the only language of choice. 222 The TIOBE index~\cite{TIOBE} for February 202 3ranks the top six most \emph{popular} programming languages as C 17.4\%, \Index*{Java} 12\%, Python 12\%, \Index*[C++]{\CC{}} 7.6\%, \Csharp 4\%, Visual Basic 3.8\% = 56.8\%, where the next 50 languages are less than 2\% each, with a long tail.220 The TIOBE index~\cite{TIOBE} for February 2021 ranks the top six most \emph{popular} programming languages as C 17.4\%, \Index*{Java} 12\%, Python 12\%, \Index*[C++]{\CC{}} 7.6\%, \Csharp 4\%, Visual Basic 3.8\% = 56.8\%, where the next 50 languages are less than 2\% each, with a long tail. 223 221 The top 4 rankings over the past 35 years are: 224 222 \begin{center} … … 240 238 however, it largely extended the C language, and did not address many of C's existing problems.\footnote{% 241 239 Two important existing problems addressed were changing the type of character literals from ©int© to ©char© and enumerator from ©int© to the type of its enumerators.} 242 \Index*{Fortran}~\cite{Fortran08}, \Index*{Cobol}~\cite{Cobol14}, and \Index*{Ada}~\cite{Ada1 6} are examples of programming languages that took an evolutionary approach, where modern language-features (\eg objects, concurrency) are added and problems fixed within the framework of the existing language.240 \Index*{Fortran}~\cite{Fortran08}, \Index*{Cobol}~\cite{Cobol14}, and \Index*{Ada}~\cite{Ada12} are examples of programming languages that took an evolutionary approach, where modern language-features (\eg objects, concurrency) are added and problems fixed within the framework of the existing language. 243 241 \Index*{Java}~\cite{Java8}, \Index*{Go}~\cite{Go}, \Index*{Rust}~\cite{Rust} and \Index*{D}~\cite{D} are examples of the revolutionary approach for modernizing C/\CC, resulting in a new language rather than an extension of the descendent. 244 242 These languages have different syntax and semantics from C, do not interoperate directly with C, and are not systems languages because of restrictive memory-management or garbage collection. … … 265 263 % extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC{}} approach of object-oriented extensions. 266 264 \CFA{}\hspace{1pt}'s polymorphism was originally formalized by \Index*{Glen Ditchfield}\index{Ditchfield, Glen}~\cite{Ditchfield92}, and first implemented by \Index*{Richard Bilson}\index{Bilson, Richard}~\cite{Bilson03}. 267 However, at that time, there was little interest in extending C, so work did not continue.265 However, at that time, there was little interesting in extending C, so work did not continue. 268 266 As the saying goes, ``\Index*{What goes around, comes around.}'', and there is now renewed interest in the C programming language because of the legacy code-base, so the \CFA project was restarted in 2015. 269 267 … … 274 272 \CFA is designed to integrate directly with existing C programs and libraries. 275 273 The most important feature of \Index{interoperability} is using the same \Index{calling convention}s, so there is no complex interface or overhead to call existing C routines. 276 This feature allows \CFA programmers to take advantage of the existing panoply of C libraries to access thousands of software features.274 This feature allows \CFA programmers to take advantage of the existing panoply of C libraries to access thousands of external software features. 277 275 Language developers often state that adequate \Index{library support} takes more work than designing and implementing the language itself. 278 276 Fortunately, \CFA, like \Index*[C++]{\CC{}}, starts with immediate access to all exiting C libraries, and in many cases, can easily wrap library routines with simpler and safer interfaces, at zero or very low cost. … … 322 320 However, it is necessary to differentiate between C and \CFA code because of name \Index{overload}ing, as for \CC. 323 321 For example, the C math-library provides the following routines for computing the absolute value of the basic types: ©abs©, ©labs©, ©llabs©, ©fabs©, ©fabsf©, ©fabsl©, ©cabsf©, ©cabs©, and ©cabsl©. 324 Whereas, \CFA wraps these routines into one overloaded name ©abs©:325 \begin{cfa} 326 unsigned char ®abs®( signed char ); §\C[3.5in]{// no C equivalent}§ 327 extern "C" { int ®abs®( int ); } §\C{// C abs}§328 unsigned long int ®abs®( long int ); §\C{// C labs}§ 329 unsigned long long int ®abs®( long long int ); §\C{// C llabs}§ 330 float ®abs®( float ); §\C{// C fabsf}§331 double ®abs®( double ); §\C{// C fabs}§332 long double ®abs®( long double ); §\C{// C fabsl}§333 float _Complex ®abs®( float _Complex ); §\C{// C cabsf}§334 double _Complex ®abs®( double _Complex ); §\C{// C cabs}§335 long double _Complex ®abs®( long double _Complex ); §\C{// C cabsl}\CRT§322 Whereas, \CFA wraps each of these routines into one overloaded name ©abs©: 323 \begin{cfa} 324 char ®abs®( char ); 325 extern "C" { int ®abs®( int ); } §\C{// use default C routine for int}§ 326 long int ®abs®( long int ); 327 long long int ®abs®( long long int ); 328 float ®abs®( float ); 329 double ®abs®( double ); 330 long double ®abs®( long double ); 331 float _Complex ®abs®( float _Complex ); 332 double _Complex ®abs®( double _Complex ); 333 long double _Complex ®abs®( long double _Complex ); 336 334 \end{cfa} 337 335 The problem is a \Index{name clash} between the C name ©abs© and the \CFA names ©abs©, resulting in two name linkages\index{C linkage}: ©extern "C"© and ©extern "Cforall"© (default). … … 341 339 342 340 This example illustrates a core idea in \CFA: \emph{the \Index{power of a name}}. 343 The name ``©abs©'' evokes the notion of absolute value and many mathematical types provide the notion of absolute value.344 Hence, knowing the name ©abs© is sufficient to apply it to any applicable type.341 The name ``©abs©'' evokes the notion of absolute value, and many mathematical types provide the notion of absolute value. 342 Hence, knowing the name ©abs© is sufficient to apply it to any type where it is applicable. 345 343 The time savings and safety of using one name uniformly versus $N$ unique names cannot be underestimated. 346 344 347 345 348 346 \section{\CFA Compilation} 349 350 \CFA is a \newterm{transpiler}, meaning it reads in a programming language (\CFA) as input and generates another programming language (C) as output, whereas a \newterm{compiler} reads in a programming language and generates assembler/machine code.351 Hence, \CFA is like the C preprocessor modifying a program and sending it on to another step for further transformation.352 The order of transformation is C preprocessor, \CFA, and finally GNU C compiler, which also has a number of transformation steps, such as assembler and linker.353 347 354 348 The command ©cfa© is used to compile a \CFA program and is based on the \Index{GNU} \Indexc{gcc} command, \eg: … … 450 444 which conditionally includes the correct header file, if the program is compiled using \Indexc{gcc} or \Indexc{cfa}. 451 445 452 The \CFA \Index{transpiler} has multiple internalsteps.453 The following flags control how the \CFA transpiler works, the stages run, and printing within a stage.446 The \CFA translator has multiple steps. 447 The following flags control how the translator works, the stages run, and printing within a stage. 454 448 The majority of these flags are used by \CFA developers, but some are occasionally useful to programmers. 455 Each option must be escaped with \Indexc{-XCFA}\index{trans piler option!-XCFA@{©-XCFA©}} to direct it to the \CFA compilationstep, similar to the ©-Xlinker© flag for the linker, \eg:449 Each option must be escaped with \Indexc{-XCFA}\index{translator option!-XCFA@{©-XCFA©}} to direct it to the compiler step, similar to the ©-Xlinker© flag for the linker, \eg: 456 450 \begin{lstlisting}[language=sh] 457 451 cfa §test§.cfa -CFA -XCFA -p # print translated code without printing the standard prelude … … 464 458 \begin{description}[topsep=5pt,itemsep=0pt,parsep=0pt] 465 459 \item 466 \Indexc{-c}\index{trans piler option!-c@{©-c©}}, \Indexc{--colors}\index{transpiler option!--colors@{©--colors©}} \, diagnostic color: ©never©, ©always©, \lstinline[deletekeywords=auto]{auto}467 \item 468 \Indexc{-g}\index{trans piler option!-g@{©-g©}}, \Indexc{--gdb}\index{transpiler option!--gdb@{©--gdb©}} \, wait for gdb to attach469 \item 470 \Indexc{-h}\index{trans piler option!-h@{©-h©}}, \Indexc{--help}\index{transpiler option!--help@{©--help©}} \, print transpiler help message471 \item 472 \Indexc{-i}\index{trans piler option!-i@{©-i©}}, \Indexc{--invariant}\index{transpiler option!--invariant@{©--invariant©}} \, invariant checking during AST passes473 \item 474 \Indexc{-l}\index{trans piler option!-l@{©-l©}}, \Indexc{--libcfa}\index{transpiler option!--libcfa@{©--libcfa©}} \, generate ©libcfa.c©475 \item 476 \Indexc{-L}\index{trans piler option!-L@{©-L©}}, \Indexc{--linemarks}\index{transpiler option!--linemarks@{©--linemarks©}} \, generate line marks477 \item 478 \Indexc{-m}\index{trans piler option!-m@{©-m©}}, \Indexc{--no-main}\index{transpiler option!--no-main@{©--no-main©}} \, do not replace main479 \item 480 \Indexc{-N}\index{trans piler option!-N@{©-N©}}, \Indexc{--no-linemarks}\index{transpiler option!--no-linemarks@{©--no-linemarks©}} \, do not generate line marks481 \item 482 \Indexc{-n}\index{trans piler option!-n@{©-n©}}, \Indexc{--no-prelude}\index{transpiler option!--no-prelude@{©--no-prelude©}} \, do not read prelude483 \item 484 \Indexc{-p}\index{trans piler option!-p@{©-p©}}, \Indexc{--prototypes}\index{transpiler option!--prototypes@{©--prototypes©}} \, do not generate prelude prototypes $\Rightarrow$ prelude not printed485 \item 486 \Indexc{-d}\index{trans piler option!-d@{©-d©}}, \Indexc{--deterministic-out}\index{transpiler option!--deterministic-out@{©--deterministic-out©}} \, only print deterministic output487 \item 488 \Indexc{-P}\index{trans piler option!-P@{©-P©}}, \Indexc{--print}\index{transpiler option!--print@{©--print©}} \, one of:460 \Indexc{-c}\index{translator option!-c@{©-c©}}, \Indexc{--colors}\index{translator option!--colors@{©--colors©}} \, diagnostic color: ©never©, ©always©, \lstinline[deletekeywords=auto]{auto} 461 \item 462 \Indexc{-g}\index{translator option!-g@{©-g©}}, \Indexc{--gdb}\index{translator option!--gdb@{©--gdb©}} \, wait for gdb to attach 463 \item 464 \Indexc{-h}\index{translator option!-h@{©-h©}}, \Indexc{--help}\index{translator option!--help@{©--help©}} \, print translator help message 465 \item 466 \Indexc{-i}\index{translator option!-i@{©-i©}}, \Indexc{--invariant}\index{translator option!--invariant@{©--invariant©}} \, invariant checking during AST passes 467 \item 468 \Indexc{-l}\index{translator option!-l@{©-l©}}, \Indexc{--libcfa}\index{translator option!--libcfa@{©--libcfa©}} \, generate ©libcfa.c© 469 \item 470 \Indexc{-L}\index{translator option!-L@{©-L©}}, \Indexc{--linemarks}\index{translator option!--linemarks@{©--linemarks©}} \, generate line marks 471 \item 472 \Indexc{-m}\index{translator option!-m@{©-m©}}, \Indexc{--no-main}\index{translator option!--no-main@{©--no-main©}} \, do not replace main 473 \item 474 \Indexc{-N}\index{translator option!-N@{©-N©}}, \Indexc{--no-linemarks}\index{translator option!--no-linemarks@{©--no-linemarks©}} \, do not generate line marks 475 \item 476 \Indexc{-n}\index{translator option!-n@{©-n©}}, \Indexc{--no-prelude}\index{translator option!--no-prelude@{©--no-prelude©}} \, do not read prelude 477 \item 478 \Indexc{-p}\index{translator option!-p@{©-p©}}, \Indexc{--prototypes}\index{translator option!--prototypes@{©--prototypes©}} \, do not generate prelude prototypes $\Rightarrow$ prelude not printed 479 \item 480 \Indexc{-d}\index{translator option!-d@{©-d©}}, \Indexc{--deterministic-out}\index{translator option!--deterministic-out@{©--deterministic-out©}} \, only print deterministic output 481 \item 482 \Indexc{-P}\index{translator option!-P@{©-P©}}, \Indexc{--print}\index{translator option!--print@{©--print©}} \, one of: 489 483 \begin{description}[topsep=0pt,itemsep=0pt,parsep=0pt] 490 484 \item 491 \Indexc{ascodegen}\index{trans piler option!-P@{©-P©}!©ascodegen©}\index{transpiler option!--print@{©-print©}!©ascodegen©} \, print AST as codegen rather than AST492 \item 493 \Indexc{asterr}\index{trans piler option!-P@{©-P©}!©asterr©}\index{transpiler option!--print@{©-print©}!©asterr©} \, print AST on error494 \item 495 \Indexc{declstats}\index{trans piler option!-P@{©-P©}!©declstats©}\index{transpiler option!--print@{©-print©}!©declstats©} \, print code property statistics496 \item 497 \Indexc{parse}\index{trans piler option!-P@{©-P©}!©parse©}\index{transpiler option!--print@{©-print©}!©parse©} \, print yacc (parsing) debug information498 \item 499 \Indexc{pretty}\index{trans piler option!-P@{©-P©}!©pretty©}\index{transpiler option!--print@{©-print©}!©pretty©} \, prettyprint for ©ascodegen© flag500 \item 501 \Indexc{rproto}\index{trans piler option!-P@{©-P©}!©rproto©}\index{transpiler option!--print@{©-print©}!©rproto©} \, resolver-proto instance502 \item 503 \Indexc{rsteps}\index{trans piler option!-P@{©-P©}!©rsteps©}\index{transpiler option!--print@{©-print©}!©rsteps©} \, print resolver steps504 \item 505 \Indexc{ast}\index{trans piler option!-P@{©-P©}!©ast©}\index{transpiler option!--print@{©-print©}!©ast©} \, print AST after parsing506 \item 507 \Indexc{excpdecl}\index{trans piler option!-P@{©-P©}!©excpdecl©}\index{transpiler option!--print@{©-print©}!©excpdecl©} \, print AST after translating exception decls508 \item 509 \Indexc{symevt}\index{trans piler option!-P@{©-P©}!©symevt©}\index{transpiler option!--print@{©-print©}!©symevt©} \, print AST after symbol table events510 \item 511 \Indexc{expralt}\index{trans piler option!-P@{©-P©}!©expralt©}\index{transpiler option!--print@{©-print©}!©expralt©} \, print AST after expressions alternatives512 \item 513 \Indexc{valdecl}\index{trans piler option!-P@{©-P©}!©valdecl©}\index{transpiler option!--print@{©-print©}!©valdecl©} \, print AST after declaration validation pass514 \item 515 \Indexc{bresolver}\index{trans piler option!-P@{©-P©}!©bresolver©}\index{transpiler option!--print@{©-print©}!©bresolver©} \, print AST before resolver step516 \item 517 \Indexc{expranly}\index{trans piler option!-P@{©-P©}!©expranly©}\index{transpiler option!--print@{©-print©}!©expranly©} \, print AST after expression analysis518 \item 519 \Indexc{ctordtor}\index{trans piler option!-P@{©-P©}!©ctordtor©}\index{transpiler option!--print@{©-print©}!©ctordtor©} \, print AST after ctor/dtor are replaced520 \item 521 \Indexc{tuple}\index{trans piler option!-P@{©-P©}!©tuple©}\index{transpiler option!--print@{©-print©}!©tuple©} \, print AST after tuple expansion522 \item 523 \Indexc{instgen}\index{trans piler option!-P@{©-P©}!©instgen©}\index{transpiler option!--print@{©-print©}!©instgen©} \, print AST after instantiate generics524 \item 525 \Indexc{bbox}\index{trans piler option!-P@{©-P©}!©bbox©}\index{transpiler option!--print@{©-print©}!©bbox©} \, print AST before box pass526 \item 527 \Indexc{bcodegen}\index{trans piler option!-P@{©-P©}!©bcodegen©}\index{transpiler option!--print@{©-print©}!©bcodegen©} \, print AST before code generation485 \Indexc{ascodegen}\index{translator option!-P@{©-P©}!©ascodegen©}\index{translator option!--print@{©-print©}!©ascodegen©} \, print AST as codegen rather than AST 486 \item 487 \Indexc{asterr}\index{translator option!-P@{©-P©}!©asterr©}\index{translator option!--print@{©-print©}!©asterr©} \, print AST on error 488 \item 489 \Indexc{declstats}\index{translator option!-P@{©-P©}!©declstats©}\index{translator option!--print@{©-print©}!©declstats©} \, print code property statistics 490 \item 491 \Indexc{parse}\index{translator option!-P@{©-P©}!©parse©}\index{translator option!--print@{©-print©}!©parse©} \, print yacc (parsing) debug information 492 \item 493 \Indexc{pretty}\index{translator option!-P@{©-P©}!©pretty©}\index{translator option!--print@{©-print©}!©pretty©} \, prettyprint for ©ascodegen© flag 494 \item 495 \Indexc{rproto}\index{translator option!-P@{©-P©}!©rproto©}\index{translator option!--print@{©-print©}!©rproto©} \, resolver-proto instance 496 \item 497 \Indexc{rsteps}\index{translator option!-P@{©-P©}!©rsteps©}\index{translator option!--print@{©-print©}!©rsteps©} \, print resolver steps 498 \item 499 \Indexc{ast}\index{translator option!-P@{©-P©}!©ast©}\index{translator option!--print@{©-print©}!©ast©} \, print AST after parsing 500 \item 501 \Indexc{excpdecl}\index{translator option!-P@{©-P©}!©excpdecl©}\index{translator option!--print@{©-print©}!©excpdecl©} \, print AST after translating exception decls 502 \item 503 \Indexc{symevt}\index{translator option!-P@{©-P©}!©symevt©}\index{translator option!--print@{©-print©}!©symevt©} \, print AST after symbol table events 504 \item 505 \Indexc{expralt}\index{translator option!-P@{©-P©}!©expralt©}\index{translator option!--print@{©-print©}!©expralt©} \, print AST after expressions alternatives 506 \item 507 \Indexc{valdecl}\index{translator option!-P@{©-P©}!©valdecl©}\index{translator option!--print@{©-print©}!©valdecl©} \, print AST after declaration validation pass 508 \item 509 \Indexc{bresolver}\index{translator option!-P@{©-P©}!©bresolver©}\index{translator option!--print@{©-print©}!©bresolver©} \, print AST before resolver step 510 \item 511 \Indexc{expranly}\index{translator option!-P@{©-P©}!©expranly©}\index{translator option!--print@{©-print©}!©expranly©} \, print AST after expression analysis 512 \item 513 \Indexc{ctordtor}\index{translator option!-P@{©-P©}!©ctordtor©}\index{translator option!--print@{©-print©}!©ctordtor©} \, print AST after ctor/dtor are replaced 514 \item 515 \Indexc{tuple}\index{translator option!-P@{©-P©}!©tuple©}\index{translator option!--print@{©-print©}!©tuple©} \, print AST after tuple expansion 516 \item 517 \Indexc{instgen}\index{translator option!-P@{©-P©}!©instgen©}\index{translator option!--print@{©-print©}!©instgen©} \, print AST after instantiate generics 518 \item 519 \Indexc{bbox}\index{translator option!-P@{©-P©}!©bbox©}\index{translator option!--print@{©-print©}!©bbox©} \, print AST before box pass 520 \item 521 \Indexc{bcodegen}\index{translator option!-P@{©-P©}!©bcodegen©}\index{translator option!--print@{©-print©}!©bcodegen©} \, print AST before code generation 528 522 \end{description} 529 523 \item 530 524 \Indexc{--prelude-dir} <directory> \, prelude directory for debug/nodebug 531 525 \item 532 \Indexc{-S}\index{trans piler option!-S@{©-S©}!©counters,heap,time,all,none©}, \Indexc{--statistics}\index{transpiler option!--statistics@{©--statistics©}!©counters,heap,time,all,none©} <option-list> \, enable profiling information: ©counters©, ©heap©, ©time©, ©all©, ©none©533 \item 534 \Indexc{-t}\index{trans piler option!-t@{©-t©}}, \Indexc{--tree}\index{transpiler option!--tree@{©--tree©}} build in tree526 \Indexc{-S}\index{translator option!-S@{©-S©}!©counters,heap,time,all,none©}, \Indexc{--statistics}\index{translator option!--statistics@{©--statistics©}!©counters,heap,time,all,none©} <option-list> \, enable profiling information: ©counters©, ©heap©, ©time©, ©all©, ©none© 527 \item 528 \Indexc{-t}\index{translator option!-t@{©-t©}}, \Indexc{--tree}\index{translator option!--tree@{©--tree©}} build in tree 535 529 \end{description} 536 530 … … 546 540 \end{cfa} 547 541 Existing C programs with keyword clashes can be converted by prefixing the keyword identifiers with double backquotes, and eventually the identifier name can be changed to a non-keyword name. 548 \VRef[Figure]{f:HeaderFileInterposition} shows how clashes in existing C header-files \see{\VRef{s:StandardHeaders}} can be handled using preprocessor \newterm{interposition}: ©#include_next© and command-line©-I filename©.549 Several common C header-files with keyword clashes are fixed in the standard \CFA header-library, so there is largelya seamless programming-experience.542 \VRef[Figure]{f:HeaderFileInterposition} shows how clashes in existing C header-files \see{\VRef{s:StandardHeaders}} can be handled using preprocessor \newterm{interposition}: ©#include_next© and ©-I filename©. 543 Several common C header-files with keyword clashes are fixed in the standard \CFA header-library, so there is a seamless programming-experience. 550 544 551 545 \begin{figure} … … 597 591 the type suffixes ©U©, ©L©, \etc may start with an underscore ©1_U©, ©1_ll© or ©1.0E10_f©. 598 592 \end{enumerate} 599 It is significantly easier to read and enter long constants when they are broken up into smaller groupings (m ostcultures use comma and/or period among digits for the same purpose).593 It is significantly easier to read and enter long constants when they are broken up into smaller groupings (many cultures use comma and/or period among digits for the same purpose). 600 594 This extension is backwards compatible, matches with the use of underscore in variable names, and appears in \Index*{Ada} and \Index*{Java} 8. 601 595 \CC uses the single quote (©'©) as a separator, restricted within a sequence of digits, \eg ©0xaa©©'©©ff©, ©3.141©©'©©592E1©©'©©1©. 602 However, the drawback of the \CC approach is difficults parsing for IDEs between character and numeric constants, as quotes are no longer balanced (©'x'© and ©3.14©©'©©159©).603 596 604 597 605 598 \section{Exponentiation Operator} 606 599 607 C, \CC, and Java (and other programming languages) have \emph{no}exponentiation operator\index{exponentiation!operator}\index{operator!exponentiation}, \ie $x^y$, and instead use a routine, like \Indexc{pow(x,y)}, to perform the exponentiation operation.600 C, \CC, and Java (and other programming languages) have no exponentiation operator\index{exponentiation!operator}\index{operator!exponentiation}, \ie $x^y$, and instead use a routine, like \Indexc{pow(x,y)}, to perform the exponentiation operation. 608 601 \CFA extends the basic operators with the exponentiation operator ©?©\R{©\\©}©?©\index{?\\?@©?@\@?©} and ©?©\R{©\\©}©=?©\index{?\\=?@©@\@=?©}, as in, ©x ©\R{©\\©}© y© and ©x ©\R{©\\©}©= y©, which means $x^y$ and $x \leftarrow x^y$. 609 602 The priority of the exponentiation operator is between the cast and multiplicative operators, so that ©w * (int)x \ (int)y * z© is parenthesized as ©(w * (((int)x) \ ((int)y))) * z©. 610 603 611 604 There are exponentiation operators for integral and floating types, including the builtin \Index{complex} types. 612 Integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication ($O(\log y)$ or shifting if the exponent is 2).605 Integral exponentiation\index{exponentiation!unsigned integral} is performed with repeated multiplication ($O(\log y)$ multiplies or shifting if the exponent is 2). 613 606 Overflow for a large exponent or negative exponent returns zero. 614 607 Floating exponentiation\index{exponentiation!floating} is performed using \Index{logarithm}s\index{exponentiation!logarithm}, so the exponent cannot be negative. … … 627 620 T ?®\®?( T ep, unsigned long int y ); 628 621 \end{cfa} 629 A user type ©T© must define one (©1©), and multiplication (©*©) \see{\VRef{s:Operator}}.622 A user type ©T© must define multiplication, one (©1©), and ©*©. 630 623 631 624 … … 638 631 \subsection{\texorpdfstring{\LstKeywordStyle{if} / \LstKeywordStyle{while} Statement}{if / while Statement}} 639 632 640 The \Indexc{if} and \Indexc{while} expressions are extended with declarations, similar to the\Indexc{for} declaration expression.\footnote{633 The \Indexc{if}/\Indexc{while} expression allows declarations, similar to \Indexc{for} declaration expression.\footnote{ 641 634 Declarations in the \Indexc{do}-©while© condition are not useful because they appear after the loop body.} 642 635 \begin{cfa} … … 660 653 \label{s:caseClause} 661 654 662 C restricts the \Indexc{case} clause in a\Indexc{switch} statement to a single value.655 C restricts a \Indexc{case} clause in \Indexc{switch} statement to a single value. 663 656 For multiple ©case© clauses prefixing a statement within the ©switch© statement, it is necessary to have multiple ©case© clauses rather than multiple values. 664 657 Requiring a ©case© clause for each value is not in the spirit of brevity normally associated with C. … … 695 688 \end{tabular} 696 689 \end{cquote} 697 In addition, subranges are allowed to specify a contiguous set ofcase values.690 In addition, subranges are allowed to specify case values. 698 691 \begin{cquote} 699 692 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{\hspace{2em}}l@{}} … … 808 801 \end{cfa} 809 802 This situation is better handled by a list of case values \see{\VRef{s:caseClause}}. 810 811 While fall-through itself is not a problem, the problem occurs when fall-through is the default, as this semantics is unintuitive for many programmers and is different from most programming languages with a ©switch© statement. 812 Hence, default fall-through semantics results in programming errors as programmers often \emph{forget} the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through. 803 While fall-through itself is not a problem, the problem occurs when fall-through is the default, as this semantics is unintuitive to many programmers and is different from most programming languages with a ©switch© statement. 804 Hence, default fall-through semantics results in a many programming errors as programmers often \emph{forget} the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through. 813 805 814 806 \item … … 827 819 The technical problem results from the inability to ensure declaration and initialization of variables when blocks are not entered at the beginning. 828 820 There are few arguments for this kind of control flow, and therefore, there is a strong impetus to eliminate it. 821 829 822 This C idiom is known as ``\Index*{Duff's device}''~\cite{Duff83}, from this example: 830 823 \begin{cfa} … … 1003 996 with the current \Indexc{switch}/\Indexc{choose} statement. 1004 997 1005 1006 \subsection{Loop Control}1007 1008 Looping a fixed number of times, possibly with a loop index, occurs frequently.1009 \CFA condenses simply looping to facilitate coding speed and safety~\see{examples in \VRef[Figure]{f:LoopControlExamples}}.1010 1011 The \Indexc{for}, \Indexc{while}, and \Indexc{do} loop-control are extended to allow an empty conditional, which implies a comparison value of ©1© (true).1012 \begin{cfa}1013 while ( ®/* empty */® ) §\C{// while ( true )}§1014 for ( ®/* empty */® ) §\C{// for ( ; true; )}§1015 do ... while ( ®/* empty */® ) §\C{// do ... while ( true )}§1016 \end{cfa}1017 1018 998 \begin{figure} 1019 999 \begin{tabular}{@{}l@{\hspace{50pt}}|l@{}} … … 1023 1003 while () { sout | "empty"; break; } 1024 1004 do { sout | "empty"; break; } while (); 1025 for () { sout | "empty"; break; } §\C {sout | nl | nlOff;}§1005 for () { sout | "empty"; break; } §\C[3in]{sout | nl | nlOff;}§ 1026 1006 1027 1007 for ( 0 ) { sout | "A"; } sout | "zero"; §\C{sout | nl;}§ … … 1065 1045 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } §\C{sout | nl;}§ 1066 1046 for ( i; 5 : j; @ -~ -5 ~ 2 : k; 1.5 ~ @ ) { sout | i | j | k; } §\C{sout | nl;}§ 1067 for ( i; 5 : k; 1.5 ~ @ : j; @ -~ -5 ~ 2 ) { sout | i | j | k; } §\C{sout | nl;} §1047 for ( i; 5 : k; 1.5 ~ @ : j; @ -~ -5 ~ 2 ) { sout | i | j | k; } §\C{sout | nl;}\CRT§ 1068 1048 \end{cfa} 1069 1049 & … … 1128 1108 % for ( T i ; 3~9 ) => for ( T i = 3 ; i < 9; i += 1 ) // using 1 1129 1109 1130 The ©for© control is extended with 4 new loop-control operators, which are not overloadable: 1110 1111 \subsection{Loop Control} 1112 1113 Looping a fixed number of times, possibly with a loop index, occurs frequently. 1114 \CFA condenses simply looping to facilitate coding speed and safety~\see{examples in \VRef[Figure]{f:LoopControlExamples}}. 1115 1116 The \Indexc{for}, \Indexc{while}, and \Indexc{do} loop-control allow an empty conditional, which implies a comparison value of ©1© (true). 1117 \begin{cfa} 1118 while ( ®/* empty */® ) §\C{// while ( true )}§ 1119 for ( ®/* empty */® ) §\C{// for ( ; true; )}§ 1120 do ... while ( ®/* empty */® ) §\C{// do ... while ( true )}§ 1121 \end{cfa} 1122 1123 The ©for© control has 4 new loop-control operators that are not overloadable: 1131 1124 \begin{description}[itemsep=0pt,parsep=0pt] 1132 1125 \item … … 1202 1195 Similarly, the high value cannot be elided is an anonymous loop index (©1 ~ @©), as there is no index to stop the loop. 1203 1196 \item 1204 ©:© means addanother index.1197 ©:© means low another index. 1205 1198 \begin{cfa} 1206 1199 for ( i; 5 ®:® j; 2 ~ 12 ~ 3 ) §\C{// for ( typeof(i) i = 1, j = 2; i < 5 \&\& j < 12; i += 1, j += 3 )}§ … … 1219 1212 \subsection{\texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break} Statement}{Labelled continue / break Statement}} 1220 1213 1221 C \Indexc{continue} and \Indexc{break} statements are restricted to one level of nesting for a particular control structure.1214 C \Indexc{continue} and \Indexc{break} statements, for altering control flow, are restricted to one level of nesting for a particular control structure. 1222 1215 This restriction forces programmers to use \Indexc{goto} to achieve the equivalent control-flow for more than one level of nesting. 1223 1216 To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@©continue©!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@©break©!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85}, as in Java. … … 1309 1302 Furthermore, the location of the label at the \emph{beginning} of the target control structure informs the reader (\Index{eye candy}) that complex control-flow is occurring in the body of the control structure. 1310 1303 With ©goto©, the label is at the end of the control structure, which fails to convey this important clue early enough to the reader. 1311 Finally, using an explicit target for the transfer , instead of an implicit target,allows new constructs to be added or removed without affecting existing constructs.1304 Finally, using an explicit target for the transfer instead of an implicit target allows new constructs to be added or removed without affecting existing constructs. 1312 1305 Otherwise, the implicit targets of the current ©continue© and ©break©, \ie the closest enclosing loop or ©switch©, change as certain constructs are added or removed. 1313 1306 … … 1380 1373 \begin{cfa} 1381 1374 Person p 1382 ®p.®name ...; ®p.®address ...; ®p.®sex ...;§\C{// access containing fields}§1375 ®p.®name; ®p.®address; ®p.®sex; §\C{// access containing fields}§ 1383 1376 \end{cfa} 1384 1377 which extends to multiple levels of qualification for nested aggregates and multiple aggregates. 1385 1378 \begin{cfa} 1386 1379 struct Ticket { ... } t; 1387 ®p.name®.first ...; ®p.address®.street ...;§\C{// access nested fields}§1388 ®t.®departure ...; ®t.®cost ...;§\C{// access multiple aggregate}§1380 ®p.name®.first; ®p.address®.street; §\C{// access nested fields}§ 1381 ®t.®departure; ®t.®cost; §\C{// access multiple aggregate}§ 1389 1382 \end{cfa} 1390 1383 Repeated aggregate qualification is tedious and makes code difficult to read. … … 1565 1558 1566 1559 1567 \s ubsection{Non-local Exception}1560 \section{Non-local Exception} 1568 1561 1569 1562 \begin{cfa} … … 2354 2347 \subsection{Implicit String Conversions} 2355 2348 2356 The types ©char©, ©char *©, ©int©, ©double©, ©_Complex©, including different signness and sizes, implicitly convert to type ©string©. 2357 \VRef[Figure]{f:ImplicitConversionsString} shows examples of implicit conversions between C strings, integral, floating-point and complex types to ©string©. 2358 A conversions can be explicitly specified: 2359 \begin{cfa} 2360 s = string( "abc" ); §\C{// converts char * to string}§ 2361 s = string( 5 ); §\C{// converts int to string}§ 2362 s = string( 5.5 ); §\C{// converts double to string}§ 2363 \end{cfa} 2364 All conversions from ©string© to ©char *©, attempt to be safe: 2365 either by requiring the maximum length of the ©char *© storage (©strncpy©) or allocating the ©char *© storage for the string characters (ownership), meaning the programmer must free the storage. 2366 As well, a string is always null terminates, implying a minimum size of 1 character. 2367 \begin{cquote} 2368 \begin{tabular}{@{}l@{\hspace{1.75in}}|@{\hspace{15pt}}l@{}} 2369 \begin{cfa} 2370 string s = "abcde"; 2371 char cs[3]; 2372 strncpy( cs, s, sizeof(cs) ); §\C{sout | cs;}§ 2373 char * cp = s; §\C{sout | cp;}§ 2374 delete( cp ); 2375 cp = s + ' ' + s; §\C{sout | cp;}§ 2376 delete( cp ); 2377 \end{cfa} 2378 & 2379 \begin{cfa} 2380 2381 2382 ab 2383 abcde 2384 2385 abcde abcde 2386 2387 \end{cfa} 2388 \end{tabular} 2389 \end{cquote} 2349 The types ©char©, ©char *©, ©int©, ©double©, ©_Complex©, including signness and different sizes, implicitly convert to type ©string©. 2350 \VRef[Figure]{f:ImplicitStringConversions} shows examples of implicit conversion between C strings, integral, floating-point and complex types to ©string© 2351 The implicit conversions can be specified explicitly, as in: 2352 \begin{cfa} 2353 s = string( "abc" ); // converts char * to string 2354 s = string( 5 ); // converts int to string 2355 s = string( 5.5 ); // converts double to string 2356 \end{cfa} 2357 Conversions from ©string© to ©char *© are supported but with restrictions. 2358 Explicit As well, when a string is converted to a ©char *©, the storage for the ©char *© is created by the conversion operation, which must be subsequently deleted: 2359 \begin{cfa} 2360 string x = "abc"; 2361 char *p = x; // convert from string to char * 2362 ... 2363 delete p; // free storage created for p 2364 \end{cfa} 2390 2365 2391 2366 \begin{figure} … … 2395 2370 string s; 2396 2371 // conversion of char and char * to string 2397 s = 'x'; §\C {sout | s;}§2398 s = "abc"; §\C {sout | s;}§2372 s = 'x'; §\CD{sout | s;}§ 2373 s = "abc"; §\CD{sout | s;}§ 2399 2374 char cs[5] = "abc"; 2400 s = cs; §\C {sout | s;}§2375 s = cs; §\CD{sout | s;}§ 2401 2376 // conversion of integral, floating-point, and complex to string 2402 s = 45hh; §\C{sout | s;}§ 2403 s = 45h; §\C{sout | s;}§ 2404 s = -(ssize_t)MAX - 1; §\C{sout | s;}§ 2405 s = (size_t)MAX; §\C{sout | s;}§ 2406 s = 5.5; §\C{sout | s;}§ 2407 s = 5.5L; §\C{sout | s;}§ 2408 s = 5.5+3.4i; §\C{sout | s;}§ 2409 s = 5.5L+3.4Li; §\C{sout | s;}§ 2377 s = 45hh; §\CD{sout | s;}§ 2378 s = 45h; §\CD{sout | s;}§ 2379 s = -(ssize_t)MAX - 1; §\CD{sout | s;}§ 2380 s = (size_t)MAX; §\CD{sout | s;}§ 2381 s = 5.5; §\CD{sout | s;}§ 2382 s = 5.5L; §\CD{sout | s;}§ 2383 s = 5.5+3.4i; §\CD{sout | s;}§ 2384 s = 5.5L+3.4Li; §\CD{sout | s;}§ 2385 // safe conversion from string to char * 2386 strncpy( cs, s, sizeof(cs) ); §\CD{sout | cs;}§ 2387 char * cp = s; §\CD{sout | cp; // ownership}§ 2388 delete( cp ); 2389 cp = s + ' ' + s; §\CD{sout | cp; // ownership}§ 2390 delete( cp ); 2410 2391 \end{cfa} 2411 2392 & … … 2427 2408 5.5+3.4i 2428 2409 5.5+3.4i 2410 2411 5.5+ 2412 5.5+3.4i 2413 2414 5.5+3.4i 5.5+3.4i 2415 2429 2416 \end{cfa} 2430 2417 \end{tabular} 2431 \caption{Implicit Conversions to String}2432 \label{f:Implicit ConversionsString}2418 \caption{Implicit String Conversions} 2419 \label{f:ImplicitStringConversions} 2433 2420 \end{figure} 2434 2421 2435 2422 2436 \subsection{Size (length)}2437 2438 The ©size© operation returns the length of a string.2439 \begin{cfa}2440 i = size( "" ); §\C{// i is assigned 0}§2441 i = size( "abc" ); §\C{// i is assigned 3}§2442 i = size( peter ); §\C{// i is assigned 5}§2443 \end{cfa}2444 2445 2446 2423 \subsection{Comparison Operators} 2447 2424 2448 The binary \Index{relational operator}s, ©<©, ©<=©, ©>©, ©>=©, and \Index{equality operator}s, ©==©, ©!=©, compare stringsusing lexicographical ordering, where longer strings are greater than shorter strings.2425 The binary relational and equality operators ©<©, ©<=©, ©>©, ©>=©, ©==©, ©!=© compare ©string© using lexicographical ordering, where longer strings are greater than shorter strings. 2449 2426 2450 2427 2451 2428 \subsection{Concatenation} 2452 2429 2453 The binary operators \Indexc{+} and \Indexc{+=} concatenate two strings, creating the sum of the strings. 2454 \begin{cfa} 2455 s = peter + ' ' + digit; §\C{// s is assigned "PETER 0123456789"}§ 2456 s += peter; §\C{// s is assigned "PETER 0123456789PETER"}§ 2457 \end{cfa} 2430 The binary operator ©+© concatenates two strings. 2431 \begin{cfa} 2432 s = peter + digit; §\C{// s is assigned "PETER0123456789"}§ 2433 s += peter; §\C{// s is assigned "PETER0123456789PETER"}§ 2434 \end{cfa} 2435 There is also an assignment form ©+=©. 2458 2436 2459 2437 2460 2438 \subsection{Repetition} 2461 2439 2462 The binary operators \Indexc{*} and \Indexc{*=} repeat a string $N$ times. 2463 If $N = 0$, a zero length string, ©""© is returned. 2464 \begin{cfa} 2465 s = 'x' * 3; §\C{// s is assigned "PETER PETER PETER "}§ 2466 s = (peter + ' ') * 3; §\C{// s is assigned "PETER PETER PETER "}§ 2440 The binary operator \Indexc{*} returns a string that is the string repeated ©n© times. 2441 If ©n = 0©, a zero length string, ©""© is returned. 2442 \begin{cfa} 2443 s = (peter + ' ') * 3; §\C{// s is assigned "PETER PETER PETER"}§ 2444 \end{cfa} 2445 There is also an assignment form ©*=©. 2446 2447 2448 \subsection{Length} 2449 2450 The ©length© operation 2451 \begin{cfa} 2452 int length() 2453 \end{cfa} 2454 returns the length of a string variable. 2455 \begin{cfa} 2456 i = peter.length(); §\C{// i is assigned the value 5}§ 2467 2457 \end{cfa} 2468 2458 2469 2459 2470 2460 \subsection{Substring} 2471 The substring operation returns a subset of the string starting at a position in the string and traversing a length. 2472 \begin{cfa} 2473 s = peter( 2, 3 ); §\C{// s is assigned "ETE"}§ 2474 s = peter( 4, -3 ); §\C{// s is assigned "ETE", length is opposite direction}§ 2475 s = peter( 2, 8 ); §\C{// s is assigned "ETER", length is clipped to 4}§ 2476 s = peter( 0, -1 ); §\C{// s is assigned "", beyond string so clipped to null}§ 2477 s = peter(-1, -1 ); §\C{// s is assigned "R", start and length are negative}§ 2478 \end{cfa} 2461 The substring operation: 2462 \begin{cfa} 2463 string operator () (int start, int lnth); 2464 \end{cfa} 2465 performs a substring operation that returns the string starting at a specified position (©start©) in the current string, and having the specified length (©lnth©). 2479 2466 A negative starting position is a specification from the right end of the string. 2480 2467 A negative length means that characters are selected in the opposite (right to left) direction from the starting position. 2481 2468 If the substring request extends beyond the beginning or end of the string, it is clipped (shortened) to the bounds of the string. 2482 2469 If the substring request is completely outside of the original string, a null string located at the end of the original string is returned. 2470 \begin{cfa} 2471 s = peter( 2, 3 ); §\C{// s is assigned "ETE"}§ 2472 s = peter( 4, -3 ); §\C{// s is assigned "ETE", length is opposite direction}§ 2473 s = peter( 2, 8 ); §\C{// s is assigned "ETER", length is clipped to 4}§ 2474 s = peter( 0, -1 ); §\C{// s is assigned "", beyond string so clipped to null}§ 2475 s = peter(-1, -1 ); §\C{// s is assigned "R", start and length are negative}§ 2476 \end{cfa} 2483 2477 The substring operation can also appear on the left hand side of the assignment operator. 2484 2478 The substring is replaced by the value on the right hand side of the assignment. 2485 2479 The length of the right-hand-side value may be shorter, the same length, or longer than the length of the substring that is selected on the left hand side of the assignment. 2486 \begin{cfa} 2487 digit( 3, 3 ) = ""; §\C{// digit is assigned "0156789"}§2488 digit( 4, 3 ) = "xyz"; §\C{// digit is assigned "015xyz9"}§2489 digit( 7, 0 ) = "***"; §\C{// digit is assigned "015xyz***9"}§2490 digit(-4, 3 ) = "$$$"; §\C{// digit is assigned "015xyz\$\$\$9"}§2480 \begin{cfa}[mathescape=false] 2481 digit( 3, 3 ) = ""; §\C{// digit is assigned "0156789"}§ 2482 digit( 4, 3 ) = "xyz"; §\C{// digit is assigned "015xyz9"}§ 2483 digit( 7, 0 ) = "***"; §\C{// digit is assigned "015xyz***9"}§ 2484 digit(-4, 3 ) = "$$$"; §\C{// digit is assigned "015xyz\$\$\$9"}§ 2491 2485 \end{cfa} 2492 2486 A substring is treated as a pointer into the base (substringed) string rather than creating a copy of the subtext. … … 2507 2501 // e is a substring result passed by value 2508 2502 void test(string &x, string &a, string &b, string &c, string &d, string e) { 2509 §\C{// x a b c d e}§2510 a( 1, 2 ) = "aaa"; §\C{// aaaxxxxxxxxxxx aaax axx xxxxx xxxxx xxxxx}§2511 b( 2, 12 ) = "bbb"; §\C{// aaabbbxxxxxxxxx aaab abbb bbxxx xxxxx xxxxx}§2512 c( 4, 5 ) = "ccc"; §\C{// aaabbbxcccxxxxxx aaab abbb bbxccc ccxxx xxxxx}§2513 c = "yyy"; §\C{// aaabyyyxxxxxx aaab abyy yyy xxxxx xxxxx}§2514 d( 1, 3 ) = "ddd"; §\C{// aaabyyyxdddxx aaab abyy yyy dddxx xxxxx}§2515 e( 1, 3 ) = "eee"; §\C{// aaabyyyxdddxx aaab abyy yyy dddxx eeexx}§2516 x = e; §\C{// eeexx eeex exx x eeexx}§2503 §\C{// x a b c d e}§ 2504 a( 1, 2 ) = "aaa"; §\C{// aaaxxxxxxxxxxx aaax axx xxxxx xxxxx xxxxx}§ 2505 b( 2, 12 ) = "bbb"; §\C{// aaabbbxxxxxxxxx aaab abbb bbxxx xxxxx xxxxx}§ 2506 c( 4, 5 ) = "ccc"; §\C{// aaabbbxcccxxxxxx aaab abbb bbxccc ccxxx xxxxx}§ 2507 c = "yyy"; §\C{// aaabyyyxxxxxx aaab abyy yyy xxxxx xxxxx}§ 2508 d( 1, 3 ) = "ddd"; §\C{// aaabyyyxdddxx aaab abyy yyy dddxx xxxxx}§ 2509 e( 1, 3 ) = "eee"; §\C{// aaabyyyxdddxx aaab abyy yyy dddxx eeexx}§ 2510 x = e; §\C{// eeexx eeex exx x eeexx}§ 2517 2511 } 2518 2512 \end{cfa} … … 2524 2518 For example: 2525 2519 \begin{cfa} 2526 s = peter( 2 ); §\C{// s is assigned "ETER"}§2527 peter( 2 ) = "IPER"; §\C{// peter is assigned "PIPER"}§2520 s = peter( 2 ); §\C{// s is assigned "ETER"}§ 2521 peter( 2 ) = "IPER"; §\C{// peter is assigned "PIPER"}§ 2528 2522 \end{cfa} 2529 2523 It is also possible to substring using a string as the index for selecting the substring portion of the string. … … 2533 2527 For example: 2534 2528 \begin{cfa}[mathescape=false] 2535 digit( "xyz$$$" ) = "678"; §\C{// digit is assigned "0156789"}§ 2536 digit( "234") = "***"; §\C{// digit is assigned "0156789***"}§ 2537 \end{cfa} 2529 digit( "xyz$$$" ) = "678"; §\C{// digit is assigned "0156789"}§ 2530 digit( "234") = "***"; §\C{// digit is assigned "0156789***"}§ 2531 \end{cfa} 2532 %$ 2538 2533 2539 2534 … … 2575 2570 A negative starting position is a specification from the right end of the string. 2576 2571 \begin{cfa} 2577 i = peter.include( digitmask ); §\C{// i is assigned 1}§2578 i = peter.include( alphamask ); §\C{// i is assigned 6}§2572 i = peter.include( digitmask ); §\C{// i is assigned 1}§ 2573 i = peter.include( alphamask ); §\C{// i is assigned 6}§ 2579 2574 \end{cfa} 2580 2575 … … 2627 2622 \begin{cfa} 2628 2623 // remove leading blanks 2629 s = string( " ABC" ).trim( " " ); §\C{// s is assigned "ABC",}§2624 s = string( " ABC" ).trim( " " ); §\C{// s is assigned "ABC",}§ 2630 2625 // remove trailing blanks 2631 s = string( "ABC " ).trim( " ", last ); §\C{// s is assigned "ABC",}§2626 s = string( "ABC " ).trim( " ", last ); §\C{// s is assigned "ABC",}§ 2632 2627 \end{cfa} 2633 2628 … … 2656 2651 returns a string in which all occurrences of the ©from© string in the current string have been replaced by the ©to© string. 2657 2652 \begin{cfa} 2658 s = peter.replace( "E", "XX" ); §\C{// s is assigned "PXXTXXR"}§2653 s = peter.replace( "E", "XX" ); §\C{// s is assigned "PXXTXXR"}§ 2659 2654 \end{cfa} 2660 2655 The replacement is done left-to-right. 2661 2656 When an instance of the ©from© string is found and changed to the ©to© string, it is NOT examined again for further replacement. 2662 2657 2663 \subsection{Returning N+1 on Failure} 2658 2659 \section{Returning N+1 on Failure} 2664 2660 2665 2661 Any of the string search routines can fail at some point during the search. … … 2691 2687 2692 2688 2693 \subsection{C Compatibility}2694 2695 To ease conversion from C to \CFA, there are companion ©string© routines for C strings.2696 \VRef[Table]{t:CompanionStringRoutines} shows the C routines on the left that also work with ©string© and the rough equivalent ©string© opeation of the right.2697 Hence, it is possible to directly convert a block of C string operations into @string@ just by changing the2698 2699 \begin{table}2700 \begin{cquote}2701 \begin{tabular}{@{}l|l@{}}2702 \multicolumn{1}{c|}{©char []©} & \multicolumn{1}{c}{©string©} \\2703 \hline2704 ©strcpy©, ©strncpy© & ©=© \\2705 ©strcat©, ©strncat© & ©+© \\2706 ©strcmp©, ©strncmp© & ©==©, ©!=©, ©<©, ©<=©, ©>©, ©>=© \\2707 ©strlen© & ©size© \\2708 ©[]© & ©[]© \\2709 ©strstr© & ©find© \\2710 ©strcspn© & ©find_first_of©, ©find_last_of© \\2711 ©strspc© & ©find_fist_not_of©, ©find_last_not_of©2712 \end{tabular}2713 \end{cquote}2714 \caption{Companion Routines for \CFA \lstinline{string} to C Strings}2715 \label{t:CompanionStringRoutines}2716 \end{table}2717 2718 For example, this block of C code can be converted to \CFA by simply changing the type of variable ©s© from ©char []© to ©string©.2719 \begin{cfa}2720 char s[32];2721 //string s;2722 strcpy( s, "abc" ); PRINT( %s, s );2723 strncpy( s, "abcdef", 3 ); PRINT( %s, s );2724 strcat( s, "xyz" ); PRINT( %s, s );2725 strncat( s, "uvwxyz", 3 ); PRINT( %s, s );2726 PRINT( %zd, strlen( s ) );2727 PRINT( %c, s[3] );2728 PRINT( %s, strstr( s, "yzu" ) ) ;2729 PRINT( %s, strstr( s, 'y' ) ) ;2730 \end{cfa}2731 However, the conversion fails with I/O because ©printf© cannot print a ©string© using format code ©%s© because \CFA strings are not null terminated.2732 2733 2734 2689 \subsection{Input/Output Operators} 2735 2690 … … 2752 2707 Hence, enums may be overloaded with variable, enum, and function names. 2753 2708 \begin{cfa} 2754 int Foo; §\C{// type/variable separate namespaces}§2709 int Foo; §\C{// type/variable separate namespaces}§ 2755 2710 enum Foo { Bar }; 2756 enum Goo { Bar }; §\C{// overload Foo.Bar}§2757 double Bar; §\C{// overload Foo.Bar, Goo.Bar}§2711 enum Goo { Bar }; §\C[1.75in]{// overload Foo.Bar}§ 2712 double Bar; §\C{// overload Foo.Bar, Goo.Bar}\CRT§ 2758 2713 \end{cfa} 2759 2714 An anonymous enumeration injects enums with specific values into a scope. … … 2828 2783 The following examples illustrate the difference between the enumeration type and the type of its enums. 2829 2784 \begin{cfa} 2830 Math m = PI; §\C{// allowed}§2831 double d = PI; §\C{// allowed, conversion to base type}§2832 m = E; §\C{// allowed}§2833 m = Alph; §\C{// {\color{red}disallowed}}§2834 m = 3.141597; §\C{// {\color{red}disallowed}}§2835 d = m; §\C{// allowed}§2836 d = Alph; §\C{// {\color{red}disallowed}}§2837 Letter l = A; §\C{// allowed}§2838 Greek g = Alph; §\C{// allowed}§2839 l = Alph; §\C{// allowed, conversion to base type}§2840 g = A; §\C{// {\color{red}disallowed}}§2785 Math m = PI; §\C[1.5in]{// allowed}§ 2786 double d = PI; §\C{// allowed, conversion to base type}§ 2787 m = E; §\C{// allowed}§ 2788 m = Alph; §\C{// {\color{red}disallowed}}§ 2789 m = 3.141597; §\C{// {\color{red}disallowed}}§ 2790 d = m; §\C{// allowed}§ 2791 d = Alph; §\C{// {\color{red}disallowed}}§ 2792 Letter l = A; §\C{// allowed}§ 2793 Greek g = Alph; §\C{// allowed}§ 2794 l = Alph; §\C{// allowed, conversion to base type}§ 2795 g = A; §\C{// {\color{red}disallowed}}\CRT§ 2841 2796 \end{cfa} 2842 2797 … … 3407 3362 For example, consider C's \Indexc{div} function, which returns the quotient and remainder for a division of an integer value. 3408 3363 \begin{cfa} 3409 typedef struct { int quot, rem; } div_t; §\C{// from include stdlib.h}§3364 typedef struct { int quot, rem; } div_t; §\C[7cm]{// from include stdlib.h}§ 3410 3365 div_t div( int num, int den ); 3411 div_t qr = div( 13, 5 ); §\C{// return quotient/remainder aggregate}§3366 div_t qr = div( 13, 5 ); §\C{// return quotient/remainder aggregate}§ 3412 3367 printf( "%d %d\n", qr.quot, qr.rem ); §\C{// print quotient/remainder}§ 3413 3368 \end{cfa} … … 3420 3375 For example, consider C's \Indexc{modf} function, which returns the integral and fractional part of a floating value. 3421 3376 \begin{cfa} 3422 double modf( double x, double * i ); §\C{// from include math.h}§3377 double modf( double x, double * i ); §\C{// from include math.h}§ 3423 3378 double intp, frac = modf( 13.5, &intp ); §\C{// return integral and fractional components}§ 3424 3379 printf( "%g %g\n", intp, frac ); §\C{// print integral/fractional components}§ … … 3449 3404 When a function call is passed as an argument to another call, the best match of actual arguments to formal parameters is evaluated given all possible expression interpretations in the current scope. 3450 3405 \begin{cfa} 3451 void g( int, int ); §\C{// 1}§3452 void g( double, double ); §\C{// 2}§3453 g( div( 13, 5 ) ); §\C{// select 1}§3454 g( modf( 13.5 ) ); §\C{// select 2}§3406 void g( int, int ); §\C{// 1}§ 3407 void g( double, double ); §\C{// 2}§ 3408 g( div( 13, 5 ) ); §\C{// select 1}§ 3409 g( modf( 13.5 ) ); §\C{// select 2}§ 3455 3410 \end{cfa} 3456 3411 In this case, there are two overloaded ©g© routines. … … 3461 3416 The previous examples can be rewritten passing the multiple returned-values directly to the ©printf© function call. 3462 3417 \begin{cfa} 3463 [ int, int ] div( int x, int y ); §\C{// from include stdlib}§3418 [ int, int ] div( int x, int y ); §\C{// from include stdlib}§ 3464 3419 printf( "%d %d\n", div( 13, 5 ) ); §\C{// print quotient/remainder}§ 3465 3420 3466 [ double, double ] modf( double x ); §\C{// from include math}§3421 [ double, double ] modf( double x ); §\C{// from include math}§ 3467 3422 printf( "%g %g\n", modf( 13.5 ) ); §\C{// print integral/fractional components}§ 3468 3423 \end{cfa} … … 3475 3430 \begin{cfa} 3476 3431 int quot, rem; 3477 [ quot, rem ] = div( 13, 5 ); §\C{// assign multiple variables}§3478 printf( "%d %d\n", quot, rem ); §\C{// print quotient/remainder}§3432 [ quot, rem ] = div( 13, 5 ); §\C{// assign multiple variables}§ 3433 printf( "%d %d\n", quot, rem ); §\C{// print quotient/remainder}\CRT§ 3479 3434 \end{cfa} 3480 3435 Here, the multiple return-values are matched in much the same way as passing multiple return-values to multiple parameters in a call. … … 3893 3848 The general syntax of a lexical list is: 3894 3849 \begin{cfa} 3895 [ §\emph{exprlist}§]3896 \end{cfa} 3897 where \LstBasicStyle{\emph{exprlist}}is a list of one or more expressions separated by commas.3850 [ $\emph{exprlist}$ ] 3851 \end{cfa} 3852 where ©$\emph{exprlist}$© is a list of one or more expressions separated by commas. 3898 3853 The brackets, ©[]©, allow differentiating between lexical lists and expressions containing the C comma operator. 3899 3854 The following are examples of lexical lists: … … 3901 3856 [ x, y, z ] 3902 3857 [ 2 ] 3903 [ v + w, x *y, 3.14159, f() ]3858 [ v+w, x*y, 3.14159, f() ] 3904 3859 \end{cfa} 3905 3860 Tuples are permitted to contain sub-tuples (\ie nesting), such as ©[ [ 14, 21 ], 9 ]©, which is a 2-element tuple whose first element is itself a tuple. … … 3913 3868 The general syntax of a tuple type is: 3914 3869 \begin{cfa} 3915 [ §\emph{typelist}§]3916 \end{cfa} 3917 where \LstBasicStyle{\emph{typelist}}is a list of one or more legal \CFA or C type specifications separated by commas, which may include other tuple type specifications.3870 [ $\emph{typelist}$ ] 3871 \end{cfa} 3872 where ©$\emph{typelist}$© is a list of one or more legal \CFA or C type specifications separated by commas, which may include other tuple type specifications. 3918 3873 Examples of tuple types include: 3919 3874 \begin{cfa} 3920 3875 [ unsigned int, char ] 3921 3876 [ double, double, double ] 3922 [ * int, int * ] §\C{// mix of CFA and ANSI}§3877 [ * int, int * ] §\C{// mix of CFA and ANSI}§ 3923 3878 [ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ] 3924 3879 \end{cfa} … … 3927 3882 Examples of declarations using tuple types are: 3928 3883 \begin{cfa} 3929 [ int, int ] x; §\C{// 2 element tuple, each element of type int}§3930 * [ char, char ] y; §\C{// pointer to a 2 element tuple}§3884 [ int, int ] x; §\C{// 2 element tuple, each element of type int}§ 3885 * [ char, char ] y; §\C{// pointer to a 2 element tuple}§ 3931 3886 [ [ int, int ] ] z ([ int, int ]); 3932 3887 \end{cfa} … … 3945 3900 [ int, int ] w1; 3946 3901 [ int, int, int ] w2; 3947 [ void ] f (int, int, int); §\C{// three input parameters of type int}§3948 [ void ] g ([ int, int, int ]); §\C{//3 element tuple as input}§3902 [ void ] f (int, int, int); §\C{// three input parameters of type int}§ 3903 [ void ] g ([ int, int, int ]); §\C{3 element tuple as input}§ 3949 3904 f( [ 1, 2, 3 ] ); 3950 3905 f( w1, 3 ); … … 4027 3982 [ int, int, int, int ] w = [ 1, 2, 3, 4 ]; 4028 3983 int x = 5; 4029 [ x, w ] = [ w, x ]; §\C{// all four tuple coercions}§3984 [ x, w ] = [ w, x ]; §\C{// all four tuple coercions}§ 4030 3985 \end{cfa} 4031 3986 Starting on the right-hand tuple in the last assignment statement, w is opened, producing a tuple of four values; … … 4045 4000 Mass assignment has the following form: 4046 4001 \begin{cfa} 4047 [ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = §\emph{expr}§;4002 [ $\emph{lvalue}$, ... , $\emph{lvalue}$ ] = $\emph{expr}$; 4048 4003 \end{cfa} 4049 4004 \index{lvalue} 4050 The left-hand side is a tuple of \ LstBasicStyle{\emph{lvalues}}, which is a list of expressions each yielding an address, \ie any data object that can appear on the left-hand side of a conventional assignment statement.4051 \LstBasicStyle{\emph{expr}}is any standard arithmetic expression.4005 The left-hand side is a tuple of \emph{lvalues}, which is a list of expressions each yielding an address, \ie any data object that can appear on the left-hand side of a conventional assignment statement. 4006 ©$\emph{expr}$© is any standard arithmetic expression. 4052 4007 Clearly, the types of the entities being assigned must be type compatible with the value of the expression. 4053 4008 … … 4086 4041 Multiple assignment has the following form: 4087 4042 \begin{cfa} 4088 [ §\emph{lvalue}§, ... , §\emph{lvalue}§ ] = [ §\emph{expr}§, ... , §\emph{expr}§];4043 [ $\emph{lvalue}$, ... , $\emph{lvalue}$ ] = [ $\emph{expr}$, ... , $\emph{expr}$ ]; 4089 4044 \end{cfa} 4090 4045 \index{lvalue} … … 4117 4072 both these examples produce indeterminate results: 4118 4073 \begin{cfa} 4119 f( x++, x++ ); §\C{// C routine call with side effects in arguments}§4120 [ v1, v2 ] = [ x++, x++ ]; §\C{// side effects in right-hand side of multiple assignment}§4074 f( x++, x++ ); §\C{// C routine call with side effects in arguments}§ 4075 [ v1, v2 ] = [ x++, x++ ]; §\C{// side effects in right-hand side of multiple assignment}§ 4121 4076 \end{cfa} 4122 4077 … … 4128 4083 Cascade assignment has the following form: 4129 4084 \begin{cfa} 4130 §\emph{tuple}§ = §\emph{tuple}§ = ... = §\emph{tuple}§;4085 $\emph{tuple}$ = $\emph{tuple}$ = ... = $\emph{tuple}$; 4131 4086 \end{cfa} 4132 4087 and it has the same parallel semantics as for mass and multiple assignment. … … 4148 4103 The goal of \CFA stream input/output (I/O) is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way. 4149 4104 Stream I/O can be implicitly or explicitly formatted. 4150 Implicit formatting means \CFA selects an I/O format for values that matches a variable's type. 4151 Explicit formatting means additional I/O information is specified to control how a value is interpreted. 4152 4105 Implicit formatting means \CFA selects the output or input format for values that matches the variable's type. 4106 Explicit formatting means additional information is specified to augment how an output or input of value is interpreted. 4153 4107 \CFA formatting incorporates ideas from C ©printf©, \CC ©stream© manipulators, and Python implicit spacing and newline. 4154 4108 Specifically: … … 4158 4112 \CFA/\CC format manipulators are named, making them easier to read and remember. 4159 4113 \item 4160 ©printf©/Python separate format codes from associated variables, making it difficult to match codes with variables.4114 ©printf©/Python separates format codes from associated variables, making it difficult to match codes with variables. 4161 4115 \CFA/\CC co-locate codes with associated variables, where \CFA has the tighter binding. 4162 4116 \item 4163 Format manipulators in ©printf©/Python/\CFA have local effect, whereas \CC have global effect, except ©setw©.4164 Hence, it is common \CCprogramming practice to toggle manipulators on and then back to the default to prevent downstream side-effects.4117 Format manipulators in \CFA have local effect, whereas \CC have global effect, except ©setw©. 4118 Hence, it is common programming practice to toggle manipulators on and then back to the default to prevent downstream side-effects. 4165 4119 Without this programming style, errors occur when moving prints, as manipulator effects incorrectly flow into the new location. 4166 4120 Furthermore, to guarantee no side-effects, manipulator values must be saved and restored across function calls. 4167 \CC programers never do any of this.4168 4121 \item 4169 4122 \CFA has more sophisticated implicit value spacing than Python, plus implicit newline at the end of a print. 4170 4123 \end{itemize} 4171 4124 4125 The standard polymorphic I/Os stream are ©stdin©/©sin© (input), ©stdout©/©sout© and ©stderr©/©serr© (output) (like C++ ©cin©/©cout©/©cerr©). 4126 Polymorphic streams ©exit© and ©abort© provide implicit program termination without and with generating a stack trace and core file. 4127 Stream ©exit© implicitly returns ©EXIT_FAILURE© to the shell. 4128 \begin{cfa} 4129 ®exit® | "x (" | x | ") negative value."; // terminate and return EXIT_FAILURE to shell 4130 ®abort® | "x (" | x | ") negative value."; // terminate and generate stack trace and core file 4131 \end{cfa} 4132 Note, \CFA stream variables ©stdin©, ©stdout©, ©stderr©, ©exit©, and ©abort© overload C variables ©stdin©, ©stdout©, ©stderr©, and functions ©exit© and ©abort©, respectively. 4133 The \CFA header file for the I/O library is \Indexc{fstream.hfa}. 4134 4172 4135 4173 4136 \subsection{Basic I/O} 4174 4175 The standard polymorphic I/O streams are ©stdin©/©sin© (input), ©stdout©/©sout©, and ©stderr©/©serr© (output) (like C++ ©cin©/©cout©/©cerr©).4176 The standard I/O operator is the bit-wise (or) operator, ©'|'©, which is used to cascade multiple I/O operations.4177 The \CFA header file for the I/O library is \Indexc{fstream.hfa}.4178 4137 4179 4138 For implicit formatted output, the common case is printing a series of variables separated by whitespace. … … 4218 4177 1®, ®2®, ®3 4®, ®5®, ®6 4219 4178 \end{cfa} 4220 The bit-wise ©|© operator is used for I/O, rather \CC shift-operators, ©<<© and ©>>©, as it is the lowest-priority \emph{overloadable} operator, other than assignment. 4221 (Operators ©||© and ©&&© are not overloadable in \CFA.) 4179 Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority \emph{overloadable} operator, other than assignment. 4222 4180 Therefore, fewer output expressions require parenthesis. 4223 4181 \begin{cquote} … … 4242 4200 \end{cquote} 4243 4201 There is a weak similarity between the \CFA logical-or operator and the \Index{Shell pipe-operator} for moving data, where data flows in the correct direction for input but the opposite direction for output. 4244 Input and output use a uniform operator, ©|©, rather than \CC's ©<<© and ©>>© input/output operators to preventthis common error in \CC:4202 Input and output use a uniform operator, ©|©, rather than \CC's ©<<© and ©>>© input/output operators, which prevents this common error in \CC: 4245 4203 \begin{C++} 4246 4204 cin << i; // why is this generating a lot of error messages? 4247 4205 \end{C++} 4248 4249 Streams ©exit© and ©abort© provide output with immediate program termination without and with generating a stack trace and core file.4250 Stream ©exit© implicitly returns ©EXIT_FAILURE© to the shell.4251 \begin{cfa}4252 ®exit® | "x (" | x | ") negative value."; §\C{// print, terminate, and return EXIT\_FAILURE to shell}§4253 ®abort® | "x (" | x | ") negative value."; §\C{// print, terminate, and generate stack trace and core file}§4254 \end{cfa}4255 Note, \CFA stream variables ©stdin©, ©stdout©, ©stderr©, ©exit©, and ©abort© overload C variables ©stdin©, ©stdout©, ©stderr©, and functions ©exit© and ©abort©, respectively.4256 4206 4257 4207 For implicit formatted input, the common case is reading a sequence of values separated by whitespace, where the type of an input constant must match with the type of the input variable. … … 4296 4246 \end{tabular} 4297 4247 \end{cquote} 4298 The format of numeric input values in the same as C constants without a trailing type suffix, as the input value-type is denoted by the input variable. 4299 For ©bool© type, the constants are ©true© and ©false©. 4300 For integral types, any number of digits, optionally preceded by a sign (©+© or ©-©), where a 4301 \begin{itemize} 4302 \item 4303 ©1©-©9© prefix introduces a decimal value (©0©-©9©), 4304 \item 4305 ©0© prefix introduces an octal value (©0©-©7©), and 4306 \item 4307 ©0x© or ©0X© prefix introduces a hexadecimal value (©0©-©f©) with lower or upper case letters. 4308 \end{itemize} 4309 For floating-point types, any number of decimal digits, optionally preceded by a sign (©+© or ©-©), optionally containing a decimal point, and optionally followed by an exponent, ©e© or ©E©, with signed (optional) decimal digits. 4310 Floating-point values can also be written in hexadecimal format preceded by ©0x© or ©0X© with hexadecimal digits and exponent denoted by ©p© or ©P©. 4311 In all cases, all whitespace characters are skipped until an appropriate value is found. 4312 \Textbf{If an appropriate value is not found, the exception ©missing_data© is raised.} 4313 4314 For the C-string type, there are two input forms: any number of \Textbf{non-whitespace} characters or a quoted sequence containing any characters except the closing quote, \ie there is no escape character supported in the string.. 4315 In both cases, the string is null terminated ©'\0'©. 4316 For the quoted string, the start and end quote characters can be any character and do not have to match \see{\ref{XXX}}. 4317 4318 \VRef[Figure]{f:IOStreamFunctions} shows the I/O stream operations for interacting with files other than ©cin©, ©cout©, and ©cerr©. 4319 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt] 4320 \item 4321 \Indexc{fail} tests the stream error-indicator, returning nonzero if it is set. 4322 \item 4323 \Indexc{clear} resets the stream error-indicator. 4324 \item 4325 \Indexc{flush} (©ofstream© only) causes any unwritten data for a stream to be written to the file. 4326 \item 4327 \Indexc{eof} (©ifstream© only) tests the end-of-file indicator for the stream pointed to by stream. 4328 Returns true if the end-of-file indicator is set, otherwise false. 4329 \item 4330 \Indexc{open} binds the file with ©name© to a stream accessed with ©mode© (see ©fopen©). 4331 \item 4332 \Indexc{close} flushes the stream and closes the file. 4333 \item 4334 \Indexc{write} (©ofstream© only) writes ©size© bytes to the stream. 4335 The bytes are written lazily when an internal buffer fills. 4336 Eager buffer writes are done with ©flush© 4337 \item 4338 \Indexc{read} (©ifstream© only) reads ©size© bytes from the stream. 4339 \item 4340 \Indexc{ungetc} (©ifstream© only) pushes the character back to the input stream. 4341 Pushed-back characters returned by subsequent reads in the reverse order of pushing. 4342 \end{itemize} 4343 The constructor functions: 4344 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt] 4345 \item 4346 create an unbound stream, which is subsequently bound to a file with ©open©. 4347 \item 4348 create a bound stream to the associated file with given ©mode©. 4349 \end{itemize} 4350 The destructor closes the stream. 4351 4352 \begin{figure} 4353 \begin{cfa} 4354 // *********************************** ofstream *********************************** 4355 bool fail( ofstream & );§\indexc{fail}\index{ofstream@©ofstream©!©fail©}§ 4356 void clear( ofstream & );§\indexc{clear}\index{ofstream@©ofstream©!©clear©}§ 4357 int flush( ofstream & );§\indexc{flush}\index{ofstream@©ofstream©!©flush©}§ 4358 void open( ofstream &, const char name[], const char mode[] = "w" );§\indexc{open}\index{ofstream@©ofstream©!©open©}§ 4359 void close( ofstream & );§\indexc{close}\index{ofstream@©ofstream©!©close©}§ 4360 ofstream & write( ofstream &, const char data[], size_t size );§\indexc{write}\index{ofstream@©ofstream©!©write©}§ 4361 void ?{}( ofstream & );§\index{ofstream@©ofstream©!©?{}©}§ 4362 void ?{}( ofstream &, const char name[], const char mode[] = "w" ); 4363 void ^?{}( ofstream & );§\index{ofstream@©ofstream©!©^?{}©}§ 4364 4365 // *********************************** ifstream *********************************** 4366 bool fail( ifstream & is );§\indexc{fail}\index{ifstream@©ifstream©!©fail©}§ 4367 void clear( ifstream & );§\indexc{clear}\index{ifstream@©ifstream©!©clear©}§ 4368 bool eof( ifstream & is );§\indexc{eof}\index{ifstream@©ifstream©!©eof©}§ 4369 void open( ifstream & is, const char name[], const char mode[] = "r" );§\indexc{open}\index{ifstream@©ifstream©!©open©}§ 4370 void close( ifstream & is );§\indexc{close}\index{ifstream@©ifstream©!©close©}§ 4371 ifstream & read( ifstream & is, char data[], size_t size );§\indexc{read}\index{ifstream@©ifstream©!©read©}§ 4372 ifstream & ungetc( ifstream & is, char c );§\indexc{unget}\index{ifstream@©ifstream©!©unget©}§ 4373 void ?{}( ifstream & is );§\index{ifstream@©ifstream©!©?{}©}§ 4374 void ?{}( ifstream & is, const char name[], const char mode[] = "r" ); 4375 void ^?{}( ifstream & is );§\index{ifstream@©ifstream©!©^?{}©}§ 4376 \end{cfa} 4377 \caption{I/O Stream Functions} 4378 \label{f:IOStreamFunctions} 4379 \end{figure} 4380 4381 \VRef[Figure]{f:CFACommand-LineProcessing} demonstrates the file operations by showing the idiomatic \CFA command-line processing and copying an input file to an output file. 4248 4249 \VRef[Figure]{f:CFACommand-LineProcessing} shows idiomatic \CFA command-line processing and copying an input file to an output file. 4382 4250 Note, a stream variable may be copied because it is a reference to an underlying stream data-structures. 4383 \Textbf{All I/O errors are handled as exceptions}, but end-of-file is not an exception as C programmers are use to explicitly checking for it.4251 All I/O errors are handles as exceptions, but end-of-file is not an exception as C programmers are use to explicitly checking for it. 4384 4252 4385 4253 \begin{figure} … … 4393 4261 try { 4394 4262 choose ( argc ) { 4395 case 3, 2:4263 case 2, 3: 4396 4264 ®open®( in, argv[1] ); §\C{// open input file first as output creates file}§ 4397 4265 if ( argc == 3 ) ®open®( out, argv[2] ); §\C{// do not create output unless input opens}§ … … 4422 4290 \end{figure} 4423 4291 4292 \VRef[Figure]{f:StreamFunctions} shows the stream operations. 4293 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt] 4294 \item 4295 \Indexc{fail} tests the stream error-indicator, returning nonzero if it is set. 4296 \item 4297 \Indexc{clear} resets the stream error-indicator. 4298 \item 4299 \Indexc{flush} (©ofstream© only) causes any unwritten data for a stream to be written to the file. 4300 \item 4301 \Indexc{eof} (©ifstream© only) tests the end-of-file indicator for the stream pointed to by stream. 4302 Returns true if the end-of-file indicator is set, otherwise false. 4303 \item 4304 \Indexc{open} binds the file with ©name© to a stream accessed with ©mode© (see ©fopen©). 4305 \item 4306 \Indexc{close} flushes the stream and closes the file. 4307 \item 4308 \Indexc{write} (©ofstream© only) writes ©size© bytes to the stream. 4309 The bytes are written lazily when an internal buffer fills. 4310 Eager buffer writes are done with ©flush© 4311 \item 4312 \Indexc{read} (©ifstream© only) reads ©size© bytes from the stream. 4313 \item 4314 \Indexc{ungetc} (©ifstream© only) pushes the character back to the input stream. 4315 Pushed-back characters returned by subsequent reads in the reverse order of pushing. 4316 \end{itemize} 4317 The constructor functions: 4318 \begin{itemize}[topsep=4pt,itemsep=2pt,parsep=0pt] 4319 \item 4320 create an unbound stream, which is subsequently bound to a file with ©open©. 4321 \item 4322 create a bound stream to the associated file with given ©mode©. 4323 \end{itemize} 4324 The destructor closes the stream. 4325 4326 \begin{figure} 4327 \begin{cfa} 4328 // *********************************** ofstream *********************************** 4329 4330 bool fail( ofstream & );§\indexc{fail}\index{ofstream@©ofstream©!©fail©}§ 4331 void clear( ofstream & );§\indexc{clear}\index{ofstream@©ofstream©!©clear©}§ 4332 int flush( ofstream & );§\indexc{flush}\index{ofstream@©ofstream©!©flush©}§ 4333 void open( ofstream &, const char name[], const char mode[] = "w" );§\indexc{open}\index{ofstream@©ofstream©!©open©}§ 4334 void close( ofstream & );§\indexc{close}\index{ofstream@©ofstream©!©close©}§ 4335 ofstream & write( ofstream &, const char data[], size_t size );§\indexc{write}\index{ofstream@©ofstream©!©write©}§ 4336 4337 void ?{}( ofstream & );§\index{ofstream@©ofstream©!©?{}©}§ 4338 void ?{}( ofstream &, const char name[], const char mode[] = "w" ); 4339 void ^?{}( ofstream & );§\index{ofstream@©ofstream©!©^?{}©}§ 4340 4341 // *********************************** ifstream *********************************** 4342 4343 bool fail( ifstream & is );§\indexc{fail}\index{ifstream@©ifstream©!©fail©}§ 4344 void clear( ifstream & );§\indexc{clear}\index{ifstream@©ifstream©!©clear©}§ 4345 bool eof( ifstream & is );§\indexc{eof}\index{ifstream@©ifstream©!©eof©}§ 4346 void open( ifstream & is, const char name[], const char mode[] = "r" );§\indexc{open}\index{ifstream@©ifstream©!©open©}§ 4347 void close( ifstream & is );§\indexc{close}\index{ifstream@©ifstream©!©close©}§ 4348 ifstream & read( ifstream & is, char data[], size_t size );§\indexc{read}\index{ifstream@©ifstream©!©read©}§ 4349 ifstream & ungetc( ifstream & is, char c );§\indexc{unget}\index{ifstream@©ifstream©!©unget©}§ 4350 4351 void ?{}( ifstream & is );§\index{ifstream@©ifstream©!©?{}©}§ 4352 void ?{}( ifstream & is, const char name[], const char mode[] = "r" ); 4353 void ^?{}( ifstream & is );§\index{ifstream@©ifstream©!©^?{}©}§ 4354 \end{cfa} 4355 \caption{Stream Functions} 4356 \label{f:StreamFunctions} 4357 \end{figure} 4358 4424 4359 4425 4360 \subsection{Implicit Separator} 4426 4361 4427 4362 The \Index{implicit separator}\index{I/O!separator} character (space/blank) is a separator not a terminator for output. 4428 The rules for implicitly adding aseparator are:4363 The rules for implicitly adding the separator are: 4429 4364 \begin{enumerate} 4430 4365 \item … … 4455 4390 \begin{cfa} 4456 4391 sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x" 4457 | 7 | " §\LstStringStyle{\textcent}§ x" | 8 | "§\LstStringStyle{\guillemotright}§x" | 9 | ") x" | 10 | "] x" | 11 | "} x";4392 | 7 | "$\LstStringStyle{\textcent}$ x" | 8 | "$\LstStringStyle{\guillemotright}$ x" | 9 | ") x" | 10 | "] x" | 11 | "} x"; 4458 4393 \end{cfa} 4459 4394 \begin{cfa}[showspaces=true] 4460 Input1®,® x 2®.® x 3®;® x 4®!® x 5®?® x 6®%® x 7§\R{\LstStringStyle{\textcent}}§ x 8§\R{\LstStringStyle{\guillemotright}}§x 9®)® x 10®]® x 11®}® x4395 1®,® x 2®.® x 3®;® x 4®!® x 5®?® x 6®%® x 7$\R{\LstStringStyle{\textcent}}$ x 8$\R{\LstStringStyle{\guillemotright}}$ x 9®)® x 10®]® x 11®}® x 4461 4396 \end{cfa} 4462 4397 4463 4398 \item 4464 4399 A separator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \LstStringStyle{([\{=\$\textsterling\textyen\textexclamdown\textquestiondown\guillemotleft}, where \LstStringStyle{\textexclamdown\textquestiondown} are inverted opening exclamation and question marks, and \LstStringStyle{\guillemotleft} is an opening citation mark. 4465 \begin{cfa} 4466 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x §\LstStringStyle{\textdollar}§" | 5 | "x §\LstStringStyle{\textsterling}§" | 6 | "x §\LstStringStyle{\textyen}§" 4467 | 7 | "x §\LstStringStyle{\textexclamdown}§" | 8 | "x §\LstStringStyle{\textquestiondown}§" | 9 | "x §\LstStringStyle{\guillemotleft}§" | 10; 4468 \end{cfa} 4400 %$ 4401 \begin{cfa} 4402 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $\LstStringStyle{\textdollar}$" | 5 | "x $\LstStringStyle{\textsterling}$" | 6 | "x $\LstStringStyle{\textyen}$" 4403 | 7 | "x $\LstStringStyle{\textexclamdown}$" | 8 | "x $\LstStringStyle{\textquestiondown}$" | 9 | "x $\LstStringStyle{\guillemotleft}$" | 10; 4404 \end{cfa} 4405 %$ 4469 4406 \begin{cfa}[showspaces=true] 4470 x ®(®1 x ®[®2 x ®{®3 x ®=®4 x §\LstStringStyle{\textdollar}§5 x §\R{\LstStringStyle{\textsterling}}§6 x §\R{\LstStringStyle{\textyen}}§7 x §\R{\LstStringStyle{\textexclamdown}}§8 x §\R{\LstStringStyle{\textquestiondown}}§9 x §\R{\LstStringStyle{\guillemotleft}}§10 4471 \end{cfa} 4407 x ®(®1 x ®[®2 x ®{®3 x ®=®4 x $\LstStringStyle{\textdollar}$5 x $\R{\LstStringStyle{\textsterling}}$6 x $\R{\LstStringStyle{\textyen}}$7 x $\R{\LstStringStyle{\textexclamdown}}$8 x $\R{\LstStringStyle{\textquestiondown}}$9 x $\R{\LstStringStyle{\guillemotleft}}$10 4408 \end{cfa} 4409 %$ 4472 4410 4473 4411 \item … … 4477 4415 \end{cfa} 4478 4416 \begin{cfa}[showspaces=true,showtabs=true] 4479 x®`®1®`®x §\R{\texttt{'}}§2§\R{\texttt{'}}§x§\R{\texttt{"}}§3§\R{\texttt{"}}§x®:®4®:®x® ®5® ®x® ®6® ®x4417 x®`®1®`®x$\R{\texttt{'}}$2$\R{\texttt{'}}$x$\R{\texttt{"}}$3$\R{\texttt{"}}$x®:®4®:®x® ®5® ®x® ®6® ®x 4480 4418 \end{cfa} 4481 4419 … … 4483 4421 If a space is desired before or after one of the special string start/end characters, explicitly insert a space. 4484 4422 \begin{cfa} 4485 sout | "x ( §\R{\texttt{\textvisiblespace}}§" | 1 | "§\R{\texttt{\textvisiblespace}}§) x" | 2 | "§\R{\texttt{\textvisiblespace}}§, x" | 3 | "§\R{\texttt{\textvisiblespace}}§:x:§\R{\texttt{\textvisiblespace}}§" | 4;4423 sout | "x ($\R{\texttt{\textvisiblespace}}$" | 1 | "$\R{\texttt{\textvisiblespace}}$) x" | 2 | "$\R{\texttt{\textvisiblespace}}$, x" | 3 | "$\R{\texttt{\textvisiblespace}}$:x:$\R{\texttt{\textvisiblespace}}$" | 4; 4486 4424 \end{cfa} 4487 4425 \begin{cfa}[showspaces=true,showtabs=true] … … 4500 4438 The separator string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters). 4501 4439 \begin{cfa}[belowskip=0pt] 4502 sepSet( sout, ", §\LstStringStyle{\textdollar}§" ); §\C{// set separator from " " to ", \$"}§4440 sepSet( sout, ", $\LstStringStyle{\textdollar}$" ); §\C{// set separator from " " to ", \$"}§ 4503 4441 sout | 1 | 2 | 3 | " \"" | ®sepVal® | "\""; 4504 4442 \end{cfa} 4505 4443 \begin{cfa}[showspaces=true,aboveskip=0pt] 4506 1®, §\color{red}\LstStringStyle{\textdollar}§®2®, §\color{red}\LstStringStyle{\textdollar}§®3 ®", §\color{red}\LstStringStyle{\textdollar}§"®4444 1®, $\color{red}\LstStringStyle{\textdollar}$®2®, $\color{red}\LstStringStyle{\textdollar}$®3 ®", $\color{red}\LstStringStyle{\textdollar}$"® 4507 4445 \end{cfa} 4508 4446 \begin{cfa}[belowskip=0pt] … … 4619 4557 For example, in: 4620 4558 \begin{cfa} 4621 int i, j;4622 4559 sin | i | ®nl® | j; 4623 4560 1 ®2® … … 4625 4562 \end{cfa} 4626 4563 variable ©i© is assigned 1, the 2 is skipped, and variable ©j© is assigned 3. 4627 For example, in:4628 \begin{cquote}4629 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}4630 \begin{cfa}4631 char ch4632 4633 sin | ch; // read X4634 4635 X4636 \end{cfa}4637 &4638 \begin{cfa}4639 4640 sin | ®nlOn®; // enable reading newlines4641 sin | ch; // read newline4642 4643 4644 \end{cfa}4645 \end{tabular}4646 \end{cquote}4647 the left example skips the newline and reads ©'X'© into ©ch©, while the right example reads the newline into ©ch©.4648 4564 4649 4565 For output: … … 4673 4589 4674 4590 4675 \subsection{Output Manipulators}4591 \subsection{Output Value Manipulators} 4676 4592 4677 4593 The following \Index{manipulator}s control formatting (printing) of the argument output values. … … 4727 4643 \item 4728 4644 \Indexc{unit}( engineering-notation )\index{manipulator!unit@©unit©} print engineering exponent as a letter between the range $10^{-24}$ and $10^{24}$: 4729 \begin{cquote}4730 4645 ©y© $\Rightarrow 10^{-24}$, ©z© $\Rightarrow 10^{-21}$, ©a© $\Rightarrow 10^{-18}$, ©f© $\Rightarrow 10^{-15}$, ©p© $\Rightarrow 10^{-12}$, ©n© $\Rightarrow 10^{-9}$, ©u© $\Rightarrow 10^{-6}$, ©m© $\Rightarrow 10^{-3}$, ©K© $\Rightarrow 10^{3}$, ©M© $\Rightarrow 10^{6}$, ©G© $\Rightarrow 10^{9}$, ©T© $\Rightarrow 10^{12}$, ©P© $\Rightarrow 10^{15}$, ©E© $\Rightarrow 10^{18}$, ©Z© $\Rightarrow 10^{21}$, ©Y© $\Rightarrow 10^{24}$. 4731 \end{cquote}4732 4646 For exponent $10^{0}$, no decimal point or letter is printed. 4733 4647 \begin{cfa}[belowskip=0pt] … … 4929 4843 // End: // 4930 4844 \end{comment} 4931 4932 4933 \subsection{Input Manipulators} 4934 4935 The following \Index{manipulator}s control scanning of input values (reading), and only affect the format of the argument. 4936 4937 Certain manipulators support a \newterm{scanset}, which is a simple regular expression, where the matching set contains any Latin-1 character (8-bits) or character ranges using minus. 4938 For example, the scanset \lstinline{"a-zA-Z -/?§"} matches any number of characters between ©'a'© and ©'z'©, between ©'A'© and ©'Z'©, between space and ©'/'©, and characters ©'?'© and (Latin-1) ©'§'©. 4845 %$ 4846 4847 4848 \subsection{Input Value Manipulators} 4849 4850 The format of numeric input values in the same as C constants without a trailing type suffix, as the input value-type is denoted by the input variable. 4851 For ©bool© type, the constants are ©true© and ©false©. 4852 For integral types, any number of digits, optionally preceded by a sign (©+© or ©-©), where a 4853 \begin{itemize} 4854 \item 4855 ©1©-©9© prefix introduces a decimal value (©0©-©9©), 4856 \item 4857 ©0© prefix introduces an octal value (©0©-©7©), and 4858 \item 4859 ©0x© or ©0X© prefix introduces a hexadecimal value (©0©-©f©) with lower or upper case letters. 4860 \end{itemize} 4861 For floating-point types, any number of decimal digits, optionally preceded by a sign (©+© or ©-©), optionally containing a decimal point, and optionally followed by an exponent, ©e© or ©E©, with signed (optional) decimal digits. 4862 Floating-point values can also be written in hexadecimal format preceded by ©0x© or ©0X© with hexadecimal digits and exponent denoted by ©p© or ©P©. 4863 4864 For the C-string type, the input values are \emph{not} the same as C-string constants, \ie double quotes bracketing arbitrary text with escape sequences. 4865 Instead, the next sequence of non-whitespace characters are read, and the input sequence is terminated with delimiter ©'\0'©. 4866 The string variable \emph{must} be large enough to contain the input sequence. 4867 To force programmers to consider buffer overruns for C-string input, C-strings can only be read with a width field, which should specify a size less than or equal to the C-string size, \eg: 4868 \begin{cfa} 4869 char line[64]; 4870 sin | wdi( ®sizeof(line)®, line ); // must specify size 4871 \end{cfa} 4872 4873 A scanset is a simple regular expression, where the matching set contains any Latin-1 character (8-bits) or character ranges using minus. 4874 For example, the scanset \lstinline{"a-zA-Z -/?§"} matches characters between ©'a'© and ©'z'©, between ©'A'© and ©'Z'©, between space and ©'/'©, and characters ©'?'© and (Latin-1) ©'§'©. 4939 4875 The following string is matched by this scanset: 4940 4876 \begin{cfa} 4941 !&%$ abAA () ZZZ ?? xx§ \S\S\S§4877 !&%$ abAA () ZZZ ?? xx§§§§ 4942 4878 \end{cfa} 4943 4879 To match a minus, put it as the first character, ©"-0-9"©. 4944 4880 Other complex forms of regular-expression matching are not supported. 4945 4881 4946 A string variable \emph{must} be large enough to contain the input sequence. 4947 To force programmers to consider buffer overruns for C-string input, C-strings can only be read with a width field, which should specify a size less than or equal to the C-string size, \eg: 4948 \begin{cfa} 4949 char line[64]; 4950 sin | wdi( ®sizeof(line)®, line ); // must specify size 4951 \end{cfa} 4952 4953 Currently, there is no mechanism to detect if a value read exceeds the capwhen Most types are finite sized, \eg integral types only store value that fit into their corresponding storage, 8, 16, 32, 64, 128 bits. 4954 Hence, an input value may be too large, and the result of the read is often considered undefined, which leads to difficlt to locate runtime errors. 4955 All reads in \CFA check if values do not fit into the argument variable's type and raise the exception 4956 All types are 4957 4882 The following \Index{manipulator}s control scanning of input values (reading), and only affect the format of the argument. 4958 4883 \begin{enumerate} 4959 4884 \item 4960 \Indexc{skip}( scanset )\index{manipulator!skip@©skip©}, ©skip©( $N$)4961 The first form uses a scanset to skip matching characters.4962 The second form skips the next $N$ characters, including newline.4885 \Indexc{skip}( pattern )\index{manipulator!skip@©skip©}, ©skip©( length ) 4886 The pattern is composed of white-space and non-white-space characters, where \emph{any} white-space character matches 0 or more input white-space characters (hence, consecutive white-space characters in the pattern are combined), and each non-white-space character matches exactly with an input character. 4887 The length is composed of the next $N$ characters, including the newline character. 4963 4888 If the match successes, the input characters are discarded, and input continues with the next character. 4964 4889 If the match fails, the input characters are left unread. 4965 4890 \begin{cfa}[belowskip=0pt] 4966 char sk[ §\,§] = "abc";4891 char sk[$\,$] = "abc"; 4967 4892 sin | "abc " | skip( sk ) | skip( 5 ); // match input sequence 4968 4893 \end{cfa} … … 4974 4899 4975 4900 \item 4976 \Indexc{wdi}( maximum, variable )\index{manipulator!wdi@©wdi©} 4977 For all types except ©char *©, whitespace is skipped until an appropriate value is found for the specified variable type. 4978 maximum is the maximum number of characters read for the current operation. 4901 \Indexc{wdi}( maximum, reference-value )\index{manipulator!wdi@©wdi©} 4902 For all types except ©char©, maximum is the maximum number of characters read for the current operation. 4979 4903 \begin{cfa}[belowskip=0pt] 4980 char ch; char ca[3]; int i; double d;4981 sin | wdi( sizeof(ch), ch ) | wdi( sizeof(ca), ca[0] ) | wdi( 3, i ) | wdi( 8, d ); // c == 'a', ca == "bcd", i == 123, d == 345.64904 char s[10]; int i; double d; 4905 sin | wdi( 4, s ) | wdi( 3, i ) | wdi( 8, d ); // c == "abcd", i == 123, d == 3.456E+2 4982 4906 \end{cfa} 4983 4907 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt] 4984 4908 ®abcd1233.456E+2® 4985 4909 \end{cfa} 4986 Here, ©ca[0]© is type ©char©, so the width reads 3 characters \Textbf{without} a null terminator.4987 4988 4910 Note, input ©wdi© cannot be overloaded with output ©wd© because both have the same parameters but return different types. 4989 4911 Currently, \CFA cannot distinguish between these two manipulators in the middle of an ©sout©/©sin© expression based on return type. 4990 4991 \item4992 \Indexc{wdi}( maximum size, ©char s[]© )\index{manipulator!wdi@©wdi©}4993 For type ©char *©, maximum is the maximum number of characters read for the current operation.4994 Any number of non-whitespace characters, stopping at the first whitespace character found. A terminating null character is automatically added at the end of the stored sequence4995 \begin{cfa}[belowskip=0pt]4996 char cstr[10];4997 sin | wdi( sizeof(cstr), cstr );4998 \end{cfa}4999 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]5000 ®abcd1233.456E+2®5001 \end{cfa}5002 5003 \item5004 \Indexc{wdi}( maximum size, maximum read, ©char s[]© )\index{manipulator!wdi@©wdi©}5005 For type ©char *©, maximum is the maximum number of characters read for the current operation.5006 \begin{cfa}[belowskip=0pt]5007 char ch; char ca[3]; int i; double d;5008 sin | wdi( sizeof(ch), ch ) | wdi( sizeof(ca), ca[0] ) | wdi( 3, i ) | wdi( 8, d ); // c == 'a', ca == "bcd", i == 123, d == 345.65009 \end{cfa}5010 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]5011 ®abcd1233.456E+2®5012 \end{cfa}5013 4912 5014 4913 \item … … 5047 4946 \end{cfa} 5048 4947 5049 \Indexc{quoted}( char delimit, wdi-input-string )\index{manipulator!quoted@©quoted©}5050 Is an ©excl© with scanset ©"delimit"©, which consumes all characters up to the delimit character.5051 If the delimit character is omitted, it defaults to ©'\n'© (newline).5052 5053 4948 \item 5054 4949 \Indexc{getline}( char delimit, wdi-input-string )\index{manipulator!getline@©getline©} 5055 Is an ©excl©with scanset ©"delimit"©, which consumes all characters up to the delimit character.4950 Is an @excl@ with scanset ©"delimit"©, which consumes all characters up to the delimit character. 5056 4951 If the delimit character is omitted, it defaults to ©'\n'© (newline). 5057 4952 \end{enumerate} … … 5063 4958 For example, if two threads execute the following: 5064 4959 \begin{cfa} 5065 §\emph{thread\(_1\)}§: sout | "abc " | "def ";5066 §\emph{thread\(_2\)}§: sout | "uvw " | "xyz ";4960 $\emph{thread\(_1\)}$ : sout | "abc " | "def "; 4961 $\emph{thread\(_2\)}$ : sout | "uvw " | "xyz "; 5067 4962 \end{cfa} 5068 4963 possible outputs are: … … 5104 4999 The common usage is the short form of the mutex statement\index{ostream@©ostream©!mutex@©mutex©} to lock a stream during a single cascaded I/O expression, \eg: 5105 5000 \begin{cfa} 5106 §\emph{thread\(_1\)}§: ®mutex( sout )® sout | "abc " | "def ";5107 §\emph{thread\(_2\)}§: ®mutex( sout )® sout | "uvw " | "xyz ";5001 $\emph{thread\(_1\)}$ : ®mutex( sout )® sout | "abc " | "def "; 5002 $\emph{thread\(_2\)}$ : ®mutex( sout )® sout | "uvw " | "xyz "; 5108 5003 \end{cfa} 5109 5004 Now, the order of the thread execution is still non-deterministic, but the output is constrained to two possible lines in either order. … … 5166 5061 Cultures use different syntax, called a \newterm{locale}, for printing numbers so they are easier to read, \eg: 5167 5062 \begin{cfa} 5168 12®,®345®.®123 §\C[1.25in]{// comma separator, period decimal-point}§5063 12®,®345®.®123 $\C[1.25in]{// comma separator, period decimal-point}$ 5169 5064 12®.®345®,®123 §\C{// period separator, comma decimal-point}§ 5170 12 §\Sp§345®,®123®.® §\C{// space separator, comma decimal-point, period terminator}\CRT§5065 12$\Sp$345®,®123®.® §\C{// space separator, comma decimal-point, period terminator}\CRT§ 5171 5066 \end{cfa} 5172 5067 A locale is selected with function ©setlocale©, and the corresponding locale package \emph{must} be installed on the underlying system; … … 5214 5109 Ukraine uk_UA.utf8 5215 5110 12 123 1 234 12 345 123 456 1 234 567 5216 12®.® 123®,®1®.® 1 §\Sp§234®,®12®.® 12§\Sp§ 345®,®123®.® 123§\Sp§ 456®,®1234®.® 1§\Sp§ 234§\Sp§567®,®12345®.®5111 12®.® 123®,®1®.® 1$\Sp$234®,®12®.® 12$\Sp$ 345®,®123®.® 123$\Sp$ 456®,®1234®.® 1$\Sp$ 234$\Sp$567®,®12345®.® 5217 5112 5218 5113 Default locale off C … … 5566 5461 5567 5462 \subsection{Operator} 5568 \label{s:Operator}5569 5463 5570 5464 \CFA also allows operators to be overloaded, to simplify the use of user-defined types. … … 7438 7332 7439 7333 \Index*[C++]{\CC{}} is a general-purpose programming language. 7440 It is an imperative, object-oriented and generic programming language, while also providing facilities for low-level memory manipulation. 7441 The primary focus of \CC was adding object-oriented programming to C, and this is the primary difference between \CC and \CFA. 7334 It has imperative, object-oriented and generic programming features, while also providing facilities for low-level memory manipulation. (Wikipedia) 7335 7336 The primary focus of \CC seems to be adding object-oriented programming to C, and this is the primary difference between \CC and Do. 7442 7337 \CC uses classes to encapsulate data and the functions that operate on that data, and to hide the internal representation of the data. 7443 7338 \CFA uses modules instead to perform these same tasks. … … 7457 7352 \subsection{Go} 7458 7353 7459 \Index*{Go}, also commonly referred to as golang, is a programming language developed at Google in 2007 ~\cite{Go}.7354 \Index*{Go}, also commonly referred to as golang, is a programming language developed at Google in 2007 [.]. 7460 7355 It is a statically typed language with syntax loosely derived from that of C, adding garbage collection, type 7461 7356 safety, some structural typing capabilities, additional built-in types such as variable-length arrays and key-value maps, and a large standard library. (Wikipedia) … … 7511 7406 In \CFA, there are ambiguous cases with dereference and operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be interpreted as: 7512 7407 \begin{cfa} 7513 *? §\Sp§*?§\C{// dereference operator, dereference operator}§7514 * §\Sp§?*?§\C{// dereference, multiplication operator}§7408 *?$\Sp$*? §\C{// dereference operator, dereference operator}§ 7409 *$\Sp$?*? §\C{// dereference, multiplication operator}§ 7515 7410 \end{cfa} 7516 7411 By default, the first interpretation is selected, which does not yield a meaningful parse. … … 7521 7416 The ambiguity occurs when the deference operator has no parameters: 7522 7417 \begin{cfa} 7523 *?() §\R{\textvisiblespace...}§;7524 *?() §\R{\textvisiblespace...}§(...) ;7418 *?()$\R{\textvisiblespace...}$ ; 7419 *?()$\R{\textvisiblespace...}$(...) ; 7525 7420 \end{cfa} 7526 7421 requiring arbitrary whitespace look-ahead for the routine-call parameter-list to disambiguate. … … 7530 7425 The remaining cases are with the increment/decrement operators and conditional expression, \eg: 7531 7426 \begin{cfa} 7532 i++? §\R{\textvisiblespace...}§(...);7533 i?++ §\R{\textvisiblespace...}§(...);7427 i++?$\R{\textvisiblespace...}$(...); 7428 i?++$\R{\textvisiblespace...}$(...); 7534 7429 \end{cfa} 7535 7430 requiring arbitrary whitespace look-ahead for the operator parameter-list, even though that interpretation is an incorrect expression (juxtaposed identifiers). 7536 7431 Therefore, it is necessary to disambiguate these cases with a space: 7537 7432 \begin{cfa} 7538 i++ §\Sp§? i : 0;7539 i? §\Sp§++i : 0;7433 i++$\Sp$? i : 0; 7434 i?$\Sp$++i : 0; 7540 7435 \end{cfa} 7541 7436 … … 7564 7459 \eg: 7565 7460 \begin{cfa} 7566 x; §\C{// int x}§7567 *y; §\C{// int *y}§7568 f( p1, p2 ); §\C{// int f( int p1, int p2 );}§7569 g( p1, p2 ) int p1, p2; §\C{// int g( int p1, int p2 );}§7461 x; §\C{// int x}§ 7462 *y; §\C{// int *y}§ 7463 f( p1, p2 ); §\C{// int f( int p1, int p2 );}§ 7464 g( p1, p2 ) int p1, p2; §\C{// int g( int p1, int p2 );}§ 7570 7465 \end{cfa} 7571 7466 \CFA continues to support K\&R routine definitions: 7572 7467 \begin{cfa} 7573 f( a, b, c ) §\C{// default int return}§7574 int a, b; char c ;§\C{// K\&R parameter declarations}§7468 f( a, b, c ) §\C{// default int return}§ 7469 int a, b; char c §\C{// K\&R parameter declarations}§ 7575 7470 { 7576 7471 ... … … 7591 7486 int rtn( int i ); 7592 7487 int rtn( char c ); 7593 rtn( 'x' ); §\C{// programmer expects 2nd rtn to be called}§7488 rtn( 'x' ); §\C{// programmer expects 2nd rtn to be called}§ 7594 7489 \end{cfa} 7595 7490 \item[Rationale:] it is more intuitive for the call to ©rtn© to match the second version of definition of ©rtn© rather than the first. … … 7613 7508 \item[Change:] make string literals ©const©: 7614 7509 \begin{cfa} 7615 char * p = "abc"; §\C{// valid in C, deprecated in \CFA}§7616 char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§7510 char * p = "abc"; §\C{// valid in C, deprecated in \CFA}§ 7511 char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§ 7617 7512 \end{cfa} 7618 7513 The type of a string literal is changed from ©[] char© to ©const [] char©. … … 7621 7516 \begin{cfa} 7622 7517 char * p = "abc"; 7623 p[0] = 'w'; §\C{// segment fault or change constant literal}§7518 p[0] = 'w'; §\C{// segment fault or change constant literal}§ 7624 7519 \end{cfa} 7625 7520 The same problem occurs when passing a string literal to a routine that changes its argument. … … 7633 7528 \item[Change:] remove \newterm{tentative definitions}, which only occurs at file scope: 7634 7529 \begin{cfa} 7635 int i; §\C{// forward definition}§7636 int *j = ®&i®; §\C{// forward reference, valid in C, invalid in \CFA}§7637 int i = 0; §\C{// definition}§7530 int i; §\C{// forward definition}§ 7531 int *j = ®&i®; §\C{// forward reference, valid in C, invalid in \CFA}§ 7532 int i = 0; §\C{// definition}§ 7638 7533 \end{cfa} 7639 7534 is valid in C, and invalid in \CFA because duplicate overloaded object definitions at the same scope level are disallowed. … … 7641 7536 \begin{cfa} 7642 7537 struct X { int i; struct X *next; }; 7643 static struct X a; §\C{// forward definition}§7644 static struct X b = { 0, ®&a® }; §\C{// forward reference, valid in C, invalid in \CFA}§7645 static struct X a = { 1, &b }; §\C{// definition}§7538 static struct X a; §\C{// forward definition}§ 7539 static struct X b = { 0, ®&a® };§\C{// forward reference, valid in C, invalid in \CFA}§ 7540 static struct X a = { 1, &b }; §\C{// definition}§ 7646 7541 \end{cfa} 7647 7542 \item[Rationale:] avoids having different initialization rules for builtin types and user-defined types. … … 7657 7552 enum ®Colour® { R, G, B, Y, C, M }; 7658 7553 struct Person { 7659 enum ®Colour® { R, G, B }; §\C{// nested type}§7660 struct Face { §\C{// nested type}§7661 ®Colour® Eyes, Hair; §\C{// type defined outside (1 level)}§7554 enum ®Colour® { R, G, B }; $\C[7cm]{// nested type}$ 7555 struct Face { §\C{// nested type}§ 7556 ®Colour® Eyes, Hair; §\C{// type defined outside (1 level)}§ 7662 7557 }; 7663 ®.Colour® shirt; §\C{// type defined outside (top level)}§7664 ®Colour® pants; §\C{// type defined same level}§7665 Face looks[10]; §\C{// type defined same level}§7558 ®.Colour® shirt; §\C{// type defined outside (top level)}§ 7559 ®Colour® pants; §\C{// type defined same level}§ 7560 Face looks[10]; §\C{// type defined same level}§ 7666 7561 }; 7667 ®Colour® c = R; §\C{// type/enum defined same level}§7668 Person®.Colour® pc = Person®.®R; §\C{// type/enum defined inside}§7669 Person®.®Face pretty; §\C{// type defined inside}§7562 ®Colour® c = R; §\C{// type/enum defined same level}§ 7563 Person®.Colour® pc = Person®.®R;§\C{// type/enum defined inside}§ 7564 Person®.®Face pretty; §\C{// type defined inside}\CRT§ 7670 7565 \end{cfa} 7671 7566 In C, the name of the nested types belongs to the same scope as the name of the outermost enclosing structure, \ie the nested types are hoisted to the scope of the outer-most type, which is not useful and confusing. … … 7744 7639 \CFA introduces the following new \Index{keyword}s, which cannot be used as identifiers. 7745 7640 7746 \begin{cquote}7747 \Indexc{basetypeof}, \Indexc{choose}, \Indexc{coroutine}, \Indexc{disable},7748 \Indexc{enable}, \Indexc{exception}, \Indexc{fallthrough}, \Indexc{fallthru},7749 \Indexc{finally}, \Indexc{fixup}, \Indexc{forall},\Indexc{generator},7750 \Indexc{int128}, \Indexc{monitor}, \Indexc{mutex}, \Indexc{one_t},7751 \Indexc{report}, \Indexc{suspend}, \Indexc{throw}, \Indexc{throwResume},7752 \Indexc{trait}, \Indexc{try}, \Indexc{virtual}, \Indexc{waitfor},7753 \Indexc{when}, \Indexc{with}, \Indexc{zero_t}7754 \end{cquote}7755 \CFA introduces the following new \Index{quasi-keyword}s, which can be used as identifiers.7756 \begin{cquote}7757 \Indexc{catch}, \Indexc{catchResume}, \Indexc{finally}, \Indexc{fixup}, \Indexc{or}, \Indexc{timeout}7758 \end{cquote}7759 7760 \begin{comment}7761 7641 \begin{cquote} 7762 7642 \begin{tabular}{@{}lllllll@{}} … … 7827 7707 \end{tabular} 7828 7708 \end{cquote} 7829 \end{comment}7830 7831 7709 7832 7710 \section{Standard Headers} 7833 7711 \label{s:StandardHeaders} 7834 7712 7835 \Celeven prescribes the following standard header-files~\cite[\S~7.1.2]{C11}: 7836 \begin{cquote} 7837 \Indexc{assert.h}, \Indexc{complex.h}, \Indexc{ctype.h}, \Indexc{errno.h}, \Indexc{fenv.h}, 7838 \Indexc[deletekeywords=float]{float.h}, \Indexc{inttypes.h}, \Indexc{iso646.h}, \Indexc{limits.h}, 7839 \Indexc{locale.h}, \Indexc{math.h}, \Indexc{setjmp.h}, \Indexc{signal.h}, \Indexc{stdalign.h}, 7840 \Indexc{stdarg.h}, \Indexc{stdatomic.h}, \Indexc{stdbool.h}, \Indexc{stddef.h}, \Indexc{stdint.h}, 7841 \Indexc{stdio.h}, \Indexc{stdlib.h}, \Indexc{stdnoreturn.h}, \Indexc{string.h}, \Indexc{tgmath.h}, 7842 \Indexc{threads.h}, \Indexc{time.h}, \Indexc{uchar.h}, \Indexc{wchar.h}, \Indexc{wctype.h} 7843 \end{cquote} 7844 and \CFA adds to this list: 7845 \begin{cquote} 7846 \Indexc{gmp.h}, \Indexc{malloc.h}, \Indexc{unistd.h} 7847 \end{cquote} 7848 \begin{comment} 7713 \Celeven prescribes the following standard header-files~\cite[\S~7.1.2]{C11} and \CFA adds to this list: 7849 7714 \begin{cquote} 7850 7715 \begin{tabular}{@{}llllll|l@{}} … … 7908 7773 \end{tabular} 7909 7774 \end{cquote} 7910 \end{comment}7911 7775 For the prescribed head-files, \CFA uses header interposition to wraps these includes in an ©extern "C"©; 7912 7776 hence, names in these include files are not mangled\index{mangling!name} \see{\VRef{s:Interoperability}}. … … 7973 7837 Type-safe allocation is provided for all C allocation routines and new \CFA allocation routines, \eg in 7974 7838 \begin{cfa} 7975 int * ip = (int *)malloc( sizeof(int) ); §\C{// C}§7976 int * ip = malloc(); §\C{// \CFA type-safe version of C malloc}§7977 int * ip = alloc(); §\C{// \CFA type-safe uniform alloc}§7839 int * ip = (int *)malloc( sizeof(int) ); §\C{// C}§ 7840 int * ip = malloc(); §\C{// \CFA type-safe version of C malloc}§ 7841 int * ip = alloc(); §\C{// \CFA type-safe uniform alloc}§ 7978 7842 \end{cfa} 7979 7843 the latter two allocations determine the allocation size from the type of ©p© (©int©) and cast the pointer to the allocated storage to ©int *©. … … 7982 7846 \begin{cfa} 7983 7847 struct S { int i; } __attribute__(( aligned( 128 ) )); // cache-line alignment 7984 S * sp = malloc(); §\C{// honour type alignment}§7848 S * sp = malloc(); §\C{// honour type alignment}§ 7985 7849 \end{cfa} 7986 7850 the storage allocation is implicitly aligned to 128 rather than the default 16. … … 7997 7861 \CFA memory management extends allocation to support constructors for initialization of allocated storage, \eg in 7998 7862 \begin{cfa} 7999 struct S { int i; }; §\C{// cache-line alignment}§7863 struct S { int i; }; §\C{// cache-line alignment}§ 8000 7864 void ?{}( S & s, int i ) { s.i = i; } 8001 7865 // assume ?|? operator for printing an S 8002 7866 8003 S & sp = *®new®( 3 ); §\C{// call constructor after allocation}§7867 S & sp = *®new®( 3 ); §\C{// call constructor after allocation}§ 8004 7868 sout | sp.i; 8005 7869 ®delete®( &sp ); 8006 7870 8007 S * spa = ®anew®( 10, 5 ); §\C{// allocate array and initialize each array element}§7871 S * spa = ®anew®( 10, 5 ); §\C{// allocate array and initialize each array element}§ 8008 7872 for ( i; 10 ) sout | spa[i] | nonl; 8009 7873 sout | nl; … … 8017 7881 extern "C" { 8018 7882 // C unsafe allocation 8019 void * malloc( size_t size ); §\indexc{malloc}§8020 void * calloc( size_t dim, size_t size ); §\indexc{calloc}§8021 void * realloc( void * ptr, size_t size ); §\indexc{realloc}§8022 void * memalign( size_t align, size_t size ); §\indexc{memalign}§8023 void * aligned_alloc( size_t align, size_t size ); §\indexc{aligned_alloc}§8024 int posix_memalign( void ** ptr, size_t align, size_t size ); §\indexc{posix_memalign}§8025 void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); §\indexc{cmemalign}§// CFA7883 void * malloc( size_t size );$\indexc{malloc}$ 7884 void * calloc( size_t dim, size_t size );$\indexc{calloc}$ 7885 void * realloc( void * ptr, size_t size );$\indexc{realloc}$ 7886 void * memalign( size_t align, size_t size );$\indexc{memalign}$ 7887 void * aligned_alloc( size_t align, size_t size );$\indexc{aligned_alloc}$ 7888 int posix_memalign( void ** ptr, size_t align, size_t size );$\indexc{posix_memalign}$ 7889 void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize );$\indexc{cmemalign}$ // CFA 8026 7890 8027 7891 // C unsafe initialization/copy 8028 void * memset( void * dest, int c, size_t size ); §\indexc{memset}§8029 void * memcpy( void * dest, const void * src, size_t size ); §\indexc{memcpy}§7892 void * memset( void * dest, int c, size_t size );$\indexc{memset}$ 7893 void * memcpy( void * dest, const void * src, size_t size );$\indexc{memcpy}$ 8030 7894 } 8031 7895 … … 8033 7897 8034 7898 forall( dtype T | sized(T) ) { 8035 // §\CFA§safe equivalents, i.e., implicit size specification7899 // $\CFA$ safe equivalents, i.e., implicit size specification 8036 7900 T * malloc( void ); 8037 7901 T * calloc( size_t dim ); … … 8042 7906 int posix_memalign( T ** ptr, size_t align ); 8043 7907 8044 // §\CFA§safe general allocation, fill, resize, alignment, array8045 T * alloc( void ); §\indexc{alloc}§ §\C[3.5in]{// variable, T size}§7908 // $\CFA$ safe general allocation, fill, resize, alignment, array 7909 T * alloc( void );$\indexc{alloc}$ $\C[3.5in]{// variable, T size}$ 8046 7910 T * alloc( size_t dim ); §\C{// array[dim], T size elements}§ 8047 7911 T * alloc( T ptr[], size_t dim ); §\C{// realloc array[dim], T size elements}§ 8048 7912 8049 T * alloc_set( char fill ); §\indexc{alloc_set}§§\C{// variable, T size, fill bytes with value}§7913 T * alloc_set( char fill );$\indexc{alloc_set}$ §\C{// variable, T size, fill bytes with value}§ 8050 7914 T * alloc_set( T fill ); §\C{// variable, T size, fill with value}§ 8051 7915 T * alloc_set( size_t dim, char fill ); §\C{// array[dim], T size elements, fill bytes with value}§ … … 8066 7930 T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); §\C{// realloc new aligned array[dim], fill new bytes with value}§ 8067 7931 8068 // §\CFA§safe initialization/copy, i.e., implicit size specification8069 T * memset( T * dest, char fill ); §\indexc{memset}§8070 T * memcpy( T * dest, const T * src ); §\indexc{memcpy}§8071 8072 // §\CFA§safe initialization/copy, i.e., implicit size specification, array types7932 // $\CFA$ safe initialization/copy, i.e., implicit size specification 7933 T * memset( T * dest, char fill );$\indexc{memset}$ 7934 T * memcpy( T * dest, const T * src );$\indexc{memcpy}$ 7935 7936 // $\CFA$ safe initialization/copy, i.e., implicit size specification, array types 8073 7937 T * amemset( T dest[], char fill, size_t dim ); 8074 7938 T * amemcpy( T dest[], const T src[], size_t dim ); 8075 7939 } 8076 7940 8077 // §\CFA§allocation/deallocation and constructor/destructor, non-array types8078 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p ); §\indexc{new}§8079 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void delete( T * ptr ); §\indexc{delete}§7941 // $\CFA$ allocation/deallocation and constructor/destructor, non-array types 7942 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * new( Params p );$\indexc{new}$ 7943 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void delete( T * ptr );$\indexc{delete}$ 8080 7944 forall( dtype T, ttype Params | sized(T) | { void ^?{}( T & ); void delete( Params ); } ) 8081 7945 void delete( T * ptr, Params rest ); 8082 7946 8083 // §\CFA§allocation/deallocation and constructor/destructor, array types8084 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p ); §\indexc{anew}§8085 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( size_t dim, T arr[] ); §\indexc{adelete}§7947 // $\CFA$ allocation/deallocation and constructor/destructor, array types 7948 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) T * anew( size_t dim, Params p );$\indexc{anew}$ 7949 forall( dtype T | sized(T) | { void ^?{}( T & ); } ) void adelete( size_t dim, T arr[] );$\indexc{adelete}$ 8086 7950 forall( dtype T | sized(T) | { void ^?{}( T & ); }, ttype Params | { void adelete( Params ); } ) 8087 7951 void adelete( size_t dim, T arr[], Params rest ); … … 8093 7957 \leavevmode 8094 7958 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8095 int ato( const char * ptr ); §\indexc{ato}§7959 int ato( const char * ptr );$\indexc{ato}$ 8096 7960 unsigned int ato( const char * ptr ); 8097 7961 long int ato( const char * ptr ); … … 8126 7990 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8127 7991 forall( T | { int ?<?( T, T ); } ) §\C{// location}§ 8128 T * bsearch( T key, const T * arr, size_t dim ); §\indexc{bsearch}§7992 T * bsearch( T key, const T * arr, size_t dim );$\indexc{bsearch}$ 8129 7993 8130 7994 forall( T | { int ?<?( T, T ); } ) §\C{// position}§ … … 8132 7996 8133 7997 forall( T | { int ?<?( T, T ); } ) 8134 void qsort( const T * arr, size_t dim ); §\indexc{qsort}§7998 void qsort( const T * arr, size_t dim );$\indexc{qsort}$ 8135 7999 8136 8000 forall( E | { int ?<?( E, E ); } ) { 8137 E * bsearch( E key, const E * vals, size_t dim ); §\indexc{bsearch}§§\C{// location}§8001 E * bsearch( E key, const E * vals, size_t dim );$\indexc{bsearch}$ §\C{// location}§ 8138 8002 size_t bsearch( E key, const E * vals, size_t dim );§\C{// position}§ 8139 E * bsearchl( E key, const E * vals, size_t dim ); §\indexc{bsearchl}§8003 E * bsearchl( E key, const E * vals, size_t dim );$\indexc{bsearchl}$ 8140 8004 size_t bsearchl( E key, const E * vals, size_t dim ); 8141 E * bsearchu( E key, const E * vals, size_t dim ); §\indexc{bsearchu}§8005 E * bsearchu( E key, const E * vals, size_t dim );$\indexc{bsearchu}$ 8142 8006 size_t bsearchu( E key, const E * vals, size_t dim ); 8143 8007 } … … 8153 8017 8154 8018 forall( E | { int ?<?( E, E ); } ) { 8155 void qsort( E * vals, size_t dim ); §\indexc{qsort}§8019 void qsort( E * vals, size_t dim );$\indexc{qsort}$ 8156 8020 } 8157 8021 \end{cfa} … … 8162 8026 \leavevmode 8163 8027 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8164 unsigned char abs( signed char ); §\indexc{abs}§8028 unsigned char abs( signed char );$\indexc{abs}$ 8165 8029 int abs( int ); 8166 8030 unsigned long int abs( long int ); … … 8177 8041 8178 8042 8179 \subsection{ CRandom Numbers}8043 \subsection{Random Numbers} 8180 8044 8181 8045 \leavevmode 8182 8046 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8183 void srandom( unsigned int seed ); §\indexc{srandom}§8184 char random( void ); §\indexc{random}§8047 void srandom( unsigned int seed );$\indexc{srandom}$ 8048 char random( void );$\indexc{random}$ 8185 8049 char random( char u ); §\C{// [0,u)}§ 8186 8050 char random( char l, char u ); §\C{// [l,u]}§ … … 8209 8073 \leavevmode 8210 8074 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8211 forall( T | { int ?<?( T, T ); } ) T min( T t1, T t2 ); §\indexc{min}§8212 forall( T | { int ?>?( T, T ); } ) T max( T t1, T t2 ); §\indexc{max}§8213 forall( T | { T min( T, T ); T max( T, T ); } ) T clamp( T value, T min_val, T max_val ); §\indexc{clamp}§8214 forall( T ) void swap( T * t1, T * t2 ); §\indexc{swap}§8075 forall( T | { int ?<?( T, T ); } ) T min( T t1, T t2 );$\indexc{min}$ 8076 forall( T | { int ?>?( T, T ); } ) T max( T t1, T t2 );$\indexc{max}$ 8077 forall( T | { T min( T, T ); T max( T, T ); } ) T clamp( T value, T min_val, T max_val );$\indexc{clamp}$ 8078 forall( T ) void swap( T * t1, T * t2 );$\indexc{swap}$ 8215 8079 \end{cfa} 8216 8080 … … 8226 8090 \leavevmode 8227 8091 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8228 float ?%?( float, float ); §\indexc{fmod}§8092 float ?%?( float, float );$\indexc{fmod}$ 8229 8093 float fmod( float, float ); 8230 8094 double ?%?( double, double ); … … 8233 8097 long double fmod( long double, long double ); 8234 8098 8235 float remainder( float, float ); §\indexc{remainder}§8099 float remainder( float, float );$\indexc{remainder}$ 8236 8100 double remainder( double, double ); 8237 8101 long double remainder( long double, long double ); 8238 8102 8239 float remquo( float, float, int * ); §\indexc{remquo}§8103 float remquo( float, float, int * );$\indexc{remquo}$ 8240 8104 double remquo( double, double, int * ); 8241 8105 long double remquo( long double, long double, int * ); … … 8248 8112 [ int, long double ] div( long double, long double ); 8249 8113 8250 float fma( float, float, float ); §\indexc{fma}§8114 float fma( float, float, float );$\indexc{fma}$ 8251 8115 double fma( double, double, double ); 8252 8116 long double fma( long double, long double, long double ); 8253 8117 8254 float fdim( float, float ); §\indexc{fdim}§8118 float fdim( float, float );$\indexc{fdim}$ 8255 8119 double fdim( double, double ); 8256 8120 long double fdim( long double, long double ); 8257 8121 8258 float nan( const char * ); §\indexc{nan}§8122 float nan( const char * );$\indexc{nan}$ 8259 8123 double nan( const char * ); 8260 8124 long double nan( const char * ); … … 8266 8130 \leavevmode 8267 8131 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8268 float exp( float ); §\indexc{exp}§8132 float exp( float );$\indexc{exp}$ 8269 8133 double exp( double ); 8270 8134 long double exp( long double ); … … 8273 8137 long double _Complex exp( long double _Complex ); 8274 8138 8275 float exp2( float ); §\indexc{exp2}§8139 float exp2( float );$\indexc{exp2}$ 8276 8140 double exp2( double ); 8277 8141 long double exp2( long double ); … … 8280 8144 // long double _Complex exp2( long double _Complex ); 8281 8145 8282 float expm1( float ); §\indexc{expm1}§8146 float expm1( float );$\indexc{expm1}$ 8283 8147 double expm1( double ); 8284 8148 long double expm1( long double ); 8285 8149 8286 float pow( float, float ); §\indexc{pow}§8150 float pow( float, float );$\indexc{pow}$ 8287 8151 double pow( double, double ); 8288 8152 long double pow( long double, long double ); … … 8297 8161 \leavevmode 8298 8162 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8299 float log( float ); §\indexc{log}§8163 float log( float );$\indexc{log}$ 8300 8164 double log( double ); 8301 8165 long double log( long double ); … … 8304 8168 long double _Complex log( long double _Complex ); 8305 8169 8306 int log2( unsigned int ); §\indexc{log2}§8170 int log2( unsigned int );$\indexc{log2}$ 8307 8171 long int log2( unsigned long int ); 8308 8172 long long int log2( unsigned long long int ) … … 8314 8178 // long double _Complex log2( long double _Complex ); 8315 8179 8316 float log10( float ); §\indexc{log10}§8180 float log10( float );$\indexc{log10}$ 8317 8181 double log10( double ); 8318 8182 long double log10( long double ); … … 8321 8185 // long double _Complex log10( long double _Complex ); 8322 8186 8323 float log1p( float ); §\indexc{log1p}§8187 float log1p( float );$\indexc{log1p}$ 8324 8188 double log1p( double ); 8325 8189 long double log1p( long double ); 8326 8190 8327 int ilogb( float ); §\indexc{ilogb}§8191 int ilogb( float );$\indexc{ilogb}$ 8328 8192 int ilogb( double ); 8329 8193 int ilogb( long double ); 8330 8194 8331 float logb( float ); §\indexc{logb}§8195 float logb( float );$\indexc{logb}$ 8332 8196 double logb( double ); 8333 8197 long double logb( long double ); 8334 8198 8335 float sqrt( float ); §\indexc{sqrt}§8199 float sqrt( float );$\indexc{sqrt}$ 8336 8200 double sqrt( double ); 8337 8201 long double sqrt( long double ); … … 8340 8204 long double _Complex sqrt( long double _Complex ); 8341 8205 8342 float cbrt( float ); §\indexc{cbrt}§8206 float cbrt( float );$\indexc{cbrt}$ 8343 8207 double cbrt( double ); 8344 8208 long double cbrt( long double ); 8345 8209 8346 float hypot( float, float ); §\indexc{hypot}§8210 float hypot( float, float );$\indexc{hypot}$ 8347 8211 double hypot( double, double ); 8348 8212 long double hypot( long double, long double ); … … 8354 8218 \leavevmode 8355 8219 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8356 float sin( float ); §\indexc{sin}§8220 float sin( float );$\indexc{sin}$ 8357 8221 double sin( double ); 8358 8222 long double sin( long double ); … … 8361 8225 long double _Complex sin( long double _Complex ); 8362 8226 8363 float cos( float ); §\indexc{cos}§8227 float cos( float );$\indexc{cos}$ 8364 8228 double cos( double ); 8365 8229 long double cos( long double ); … … 8368 8232 long double _Complex cos( long double _Complex ); 8369 8233 8370 float tan( float ); §\indexc{tan}§8234 float tan( float );$\indexc{tan}$ 8371 8235 double tan( double ); 8372 8236 long double tan( long double ); … … 8375 8239 long double _Complex tan( long double _Complex ); 8376 8240 8377 float asin( float ); §\indexc{asin}§8241 float asin( float );$\indexc{asin}$ 8378 8242 double asin( double ); 8379 8243 long double asin( long double ); … … 8382 8246 long double _Complex asin( long double _Complex ); 8383 8247 8384 float acos( float ); §\indexc{acos}§8248 float acos( float );$\indexc{acos}$ 8385 8249 double acos( double ); 8386 8250 long double acos( long double ); … … 8389 8253 long double _Complex acos( long double _Complex ); 8390 8254 8391 float atan( float ); §\indexc{atan}§8255 float atan( float );$\indexc{atan}$ 8392 8256 double atan( double ); 8393 8257 long double atan( long double ); … … 8396 8260 long double _Complex atan( long double _Complex ); 8397 8261 8398 float atan2( float, float ); §\indexc{atan2}§8262 float atan2( float, float );$\indexc{atan2}$ 8399 8263 double atan2( double, double ); 8400 8264 long double atan2( long double, long double ); 8401 8265 8402 8266 float atan( float, float ); §\C{// alternative name for atan2}§ 8403 double atan( double, double ); §\indexc{atan}§8267 double atan( double, double );$\indexc{atan}$ 8404 8268 long double atan( long double, long double ); 8405 8269 \end{cfa} … … 8410 8274 \leavevmode 8411 8275 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8412 float sinh( float ); §\indexc{sinh}§8276 float sinh( float );$\indexc{sinh}$ 8413 8277 double sinh( double ); 8414 8278 long double sinh( long double ); … … 8417 8281 long double _Complex sinh( long double _Complex ); 8418 8282 8419 float cosh( float ); §\indexc{cosh}§8283 float cosh( float );$\indexc{cosh}$ 8420 8284 double cosh( double ); 8421 8285 long double cosh( long double ); … … 8424 8288 long double _Complex cosh( long double _Complex ); 8425 8289 8426 float tanh( float ); §\indexc{tanh}§8290 float tanh( float );$\indexc{tanh}$ 8427 8291 double tanh( double ); 8428 8292 long double tanh( long double ); … … 8431 8295 long double _Complex tanh( long double _Complex ); 8432 8296 8433 float asinh( float ); §\indexc{asinh}§8297 float asinh( float );$\indexc{asinh}$ 8434 8298 double asinh( double ); 8435 8299 long double asinh( long double ); … … 8438 8302 long double _Complex asinh( long double _Complex ); 8439 8303 8440 float acosh( float ); §\indexc{acosh}§8304 float acosh( float );$\indexc{acosh}$ 8441 8305 double acosh( double ); 8442 8306 long double acosh( long double ); … … 8445 8309 long double _Complex acosh( long double _Complex ); 8446 8310 8447 float atanh( float ); §\indexc{atanh}§8311 float atanh( float );$\indexc{atanh}$ 8448 8312 double atanh( double ); 8449 8313 long double atanh( long double ); … … 8458 8322 \leavevmode 8459 8323 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8460 float erf( float ); §\indexc{erf}§8324 float erf( float );$\indexc{erf}$ 8461 8325 double erf( double ); 8462 8326 long double erf( long double ); … … 8465 8329 long double _Complex erf( long double _Complex ); 8466 8330 8467 float erfc( float ); §\indexc{erfc}§8331 float erfc( float );$\indexc{erfc}$ 8468 8332 double erfc( double ); 8469 8333 long double erfc( long double ); … … 8472 8336 long double _Complex erfc( long double _Complex ); 8473 8337 8474 float lgamma( float ); §\indexc{lgamma}§8338 float lgamma( float );$\indexc{lgamma}$ 8475 8339 double lgamma( double ); 8476 8340 long double lgamma( long double ); … … 8479 8343 long double lgamma( long double, int * ); 8480 8344 8481 float tgamma( float ); §\indexc{tgamma}§8345 float tgamma( float );$\indexc{tgamma}$ 8482 8346 double tgamma( double ); 8483 8347 long double tgamma( long double ); … … 8525 8389 unsigned long long int ceiling( unsigned long long int n, unsigned long long int align ); 8526 8390 8527 float floor( float ); §\indexc{floor}§8391 float floor( float );$\indexc{floor}$ 8528 8392 double floor( double ); 8529 8393 long double floor( long double ); 8530 8394 8531 float ceil( float ); §\indexc{ceil}§8395 float ceil( float );$\indexc{ceil}$ 8532 8396 double ceil( double ); 8533 8397 long double ceil( long double ); 8534 8398 8535 float trunc( float ); §\indexc{trunc}§8399 float trunc( float );$\indexc{trunc}$ 8536 8400 double trunc( double ); 8537 8401 long double trunc( long double ); 8538 8402 8539 float rint( float ); §\indexc{rint}§8403 float rint( float );$\indexc{rint}$ 8540 8404 long double rint( long double ); 8541 8405 long int rint( float ); … … 8546 8410 long long int rint( long double ); 8547 8411 8548 long int lrint( float ); §\indexc{lrint}§8412 long int lrint( float );$\indexc{lrint}$ 8549 8413 long int lrint( double ); 8550 8414 long int lrint( long double ); … … 8553 8417 long long int llrint( long double ); 8554 8418 8555 float nearbyint( float ); §\indexc{nearbyint}§8419 float nearbyint( float );$\indexc{nearbyint}$ 8556 8420 double nearbyint( double ); 8557 8421 long double nearbyint( long double ); 8558 8422 8559 float round( float ); §\indexc{round}§8423 float round( float );$\indexc{round}$ 8560 8424 long double round( long double ); 8561 8425 long int round( float ); … … 8566 8430 long long int round( long double ); 8567 8431 8568 long int lround( float ); §\indexc{lround}§8432 long int lround( float );$\indexc{lround}$ 8569 8433 long int lround( double ); 8570 8434 long int lround( long double ); … … 8579 8443 \leavevmode 8580 8444 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 8581 float copysign( float, float ); §\indexc{copysign}§8445 float copysign( float, float );$\indexc{copysign}$ 8582 8446 double copysign( double, double ); 8583 8447 long double copysign( long double, long double ); 8584 8448 8585 float frexp( float, int * ); §\indexc{frexp}§8449 float frexp( float, int * );$\indexc{frexp}$ 8586 8450 double frexp( double, int * ); 8587 8451 long double frexp( long double, int * ); 8588 8452 8589 float ldexp( float, int ); §\indexc{ldexp}§8453 float ldexp( float, int );$\indexc{ldexp}$ 8590 8454 double ldexp( double, int ); 8591 8455 long double ldexp( long double, int ); 8592 8456 8593 [ float, float ] modf( float ); §\indexc{modf}§8457 [ float, float ] modf( float );$\indexc{modf}$ 8594 8458 float modf( float, float * ); 8595 8459 [ double, double ] modf( double ); … … 8598 8462 long double modf( long double, long double * ); 8599 8463 8600 float nextafter( float, float ); §\indexc{nextafter}§8464 float nextafter( float, float );$\indexc{nextafter}$ 8601 8465 double nextafter( double, double ); 8602 8466 long double nextafter( long double, long double ); 8603 8467 8604 float nexttoward( float, long double ); §\indexc{nexttoward}§8468 float nexttoward( float, long double );$\indexc{nexttoward}$ 8605 8469 double nexttoward( double, long double ); 8606 8470 long double nexttoward( long double, long double ); 8607 8471 8608 float scalbn( float, int ); §\indexc{scalbn}§8472 float scalbn( float, int );$\indexc{scalbn}$ 8609 8473 double scalbn( double, int ); 8610 8474 long double scalbn( long double, int ); 8611 8475 8612 float scalbln( float, long int ); §\indexc{scalbln}§8476 float scalbln( float, long int );$\indexc{scalbln}$ 8613 8477 double scalbln( double, long int ); 8614 8478 long double scalbln( long double, long int ); … … 8870 8734 All \newterm{pseudo random-number generators} (\newterm{PRNG}) involve some technique to scramble bits of a value, \eg multiplicative recurrence: 8871 8735 \begin{cfa} 8872 rand = 3 3967 * (rand + 1063); // scramble bits8736 rand = 36973 * (rand & 65535) + (rand >> 16); // scramble bits 8873 8737 \end{cfa} 8874 8738 Multiplication of large values adds new least-significant bits and drops most-significant bits. … … 8877 8741 bits 63--32 (most) & bits 31--0 (least) \\ 8878 8742 \hline 8879 ©0x0© & ©0x3e8e36©\\8880 ©0x5f© & ©0x718c25e1©\\8881 ©0xad3e© & ©0x7b5f1dbe©\\8882 ©0xbc3b© & ©0xac69ff19©\\8883 ©0x1070f© & ©0x2d258dc6© 8743 0x0 & 0x3e8e36 \\ 8744 0x5f & 0x718c25e1 \\ 8745 0xad3e & 0x7b5f1dbe \\ 8746 0xbc3b & 0xac69ff19 \\ 8747 0x1070f & 0x2d258dc6 \\ 8884 8748 \end{tabular} 8885 8749 \end{quote} … … 8887 8751 The least-significant bits \emph{appear} random but the same bits are always generated given a fixed starting value, called the \newterm{seed} (value 0x3e8e36 above). 8888 8752 Hence, if a program uses the same seed, the same sequence of pseudo-random values is generated from the PRNG. 8889 Often the seed is set to another random value like a program's process identifier ( \Indexc{getpid}) or time when the program is run;8753 Often the seed is set to another random value like a program's process identifier (©getpid©\index{getpid@©getpid©}) or time when the program is run; 8890 8754 hence, one random value bootstraps another. 8891 8755 Finally, a PRNG usually generates a range of large values, \eg ©[0, UINT_MAX]©, which are scaled using the modulus operator, \eg ©prng() % 5© produces random values in the range 0--4. 8892 8756 8893 \CFA provides 32/64-bit sequential PRNG type only accessible by a single thread (not thread-safe) and a set of global routines and companion thread PRNG functions accessible by multiple threads without contention. 8894 To use the PRNG interface \Textbf{requires including \Indexc{stdlib.hfa}}. 8757 \CFA provides a sequential PRNG type only accessible by a single thread (not thread-safe) and a set of global and companion thread PRNG functions accessible by multiple threads without contention. 8895 8758 \begin{itemize} 8896 8759 \item 8897 The ©PRNG© types for sequential programs, including coroutining, are: 8898 \begin{cfa} 8899 struct PRNG32 {}; §\C{// opaque type, no copy or assignment}§ 8900 void ?{}( PRNG32 & prng, uint32_t seed ); §\C{// fixed seed}§ 8901 void ?{}( PRNG32 & prng ); §\C{// random seed}§ 8902 void set_seed( PRNG32 & prng, uint32_t seed ); §\C{// set seed}§ 8903 uint32_t get_seed( PRNG32 & prng ); §\C{// get seed}§ 8904 uint32_t prng( PRNG32 & prng ); §\C{// [0,UINT\_MAX]}§ 8905 uint32_t prng( PRNG32 & prng, uint32_t u ); §\C{// [0,u)}§ 8906 uint32_t prng( PRNG32 & prng, uint32_t l, uint32_t u ); §\C{// [l,u]}§ 8907 uint32_t calls( PRNG32 & prng ); §\C{// number of calls}§ 8908 void copy( PRNG32 & dst, PRNG32 & src ); §\C{// checkpoint PRNG state}§ 8909 \end{cfa} 8910 \begin{cfa} 8911 struct PRNG64 {}; §\C{// opaque type, no copy or assignment}§ 8912 void ?{}( PRNG64 & prng, uint64_t seed ); §\C{// fixed seed}§ 8913 void ?{}( PRNG64 & prng ); §\C{// random seed}§ 8914 void set_seed( PRNG64 & prng, uint64_t seed ); §\C{// set seed}§ 8915 uint64_t get_seed( PRNG64 & prng ); §\C{// get seed}§ 8916 uint64_t prng( PRNG64 & prng ); §\C{// [0,UINT\_MAX]}§ 8917 uint64_t prng( PRNG64 & prng, uint64_t u ); §\C{// [0,u)}§ 8918 uint64_t prng( PRNG64 & prng, uint64_t l, uint64_t u ); §\C{// [l,u]}§ 8919 uint64_t calls( PRNG64 & prng ); §\C{// number of calls}§ 8920 void copy( PRNG64 & dst, PRNG64 & src ); §\C{// checkpoint PRNG state}§ 8921 \end{cfa} 8922 The type ©PRNG© is aliased to ©PRNG64© on 64-bit architectures and ©PRNG32© on 32-bit architectures. 8760 The ©PRNG© type is for sequential programs, like coroutining: 8761 \begin{cfa} 8762 struct PRNG { ... }; $\C[3.75in]{// opaque type}$ 8763 void ?{}( PRNG & prng ); §\C{// random seed}§ 8764 void ?{}( PRNG & prng, uint32_t seed ); §\C{// fixed seed}§ 8765 void set_seed( PRNG & prng, uint32_t seed ); §\C{// set seed}§ 8766 uint32_t get_seed( PRNG & prng ); §\C{// get seed}§ 8767 uint32_t prng( PRNG & prng ); §\C{// [0,UINT\_MAX]}§ 8768 uint32_t prng( PRNG & prng, uint32_t u ); §\C{// [0,u)}§ 8769 uint32_t prng( PRNG & prng, uint32_t l, uint32_t u ); §\C{// [l,u]}§ 8770 uint32_t calls( PRNG & prng ); §\C{// number of calls}\CRT§ 8771 \end{cfa} 8923 8772 A ©PRNG© object is used to randomize behaviour or values during execution, \eg in games, a character makes a random move or an object takes on a random value. 8924 8773 In this scenario, it is useful to have multiple ©PRNG© objects, \eg one per player or object. 8925 However, sequential execution is still repeatable given the same starting seeds for all ©PRNG©s. 8774 However, sequential execution is still repeatable given the same starting seeds for all ©PRNG©s. 8926 8775 \VRef[Figure]{f:SequentialPRNG} shows an example that creates two sequential ©PRNG©s, sets both to the same seed (1009), and illustrates the three forms for generating random values, where both ©PRNG©s generate the same sequence of values. 8927 Note, to prevent accidental PRNG copying, the copy constructor and assignment are hidden.8928 To copy a PRNG for checkpointing, use the explicit ©copy© member.8929 8776 8930 8777 \begin{figure} 8931 8778 \begin{cfa} 8932 PRNG sprng1, sprng2; §\C{// select appropriate 32/64-bit PRNG}§8933 ®set_seed( sprng1, 1009 )®; ®set_seed( sprng2, 1009 )®;8779 PRNG prng1, prng2; 8780 ®set_seed( prng1, 1009 )®; ®set_seed( prng2, 1009 )®; 8934 8781 for ( 10 ) { 8935 8782 // Do not cascade prng calls because side-effect functions called in arbitrary order. 8936 sout | nlOff | ®prng( sprng1 )®; sout | ®prng( sprng1, 5 )®; sout | ®prng( sprng1, 0, 5 )® | '\t';8937 sout | ®prng( sprng2 )®; sout | ®prng( sprng2, 5 )®; sout | ®prng( sprng2, 0, 5 )® | nlOn;8783 sout | nlOff | ®prng( prng1 )®; sout | ®prng( prng1, 5 )®; sout | ®prng( prng1, 0, 5 )® | '\t'; 8784 sout | ®prng( prng2 )®; sout | ®prng( prng2, 5 )®; sout | ®prng( prng2, 0, 5 )® | nlOn; 8938 8785 } 8939 8786 \end{cfa} … … 8974 8821 The PRNG global and companion thread functions are for concurrent programming, such as randomizing execution in short-running programs, \eg ©yield( prng() % 5 )©. 8975 8822 \begin{cfa} 8976 void set_seed( size_t seed ); §\C{// set global seed}§8977 size_t get_seed();§\C{// get global seed}§8978 // SLOWER , global routines8979 size_t prng( void );§\C{// [0,UINT\_MAX]}§8980 size_t prng( size_t u );§\C{// [0,u)}§8981 size_t prng( size_t l, size_t u );§\C{// [l,u]}§8982 // FASTER , thread members8983 size_t prng( §thread\LstStringStyle{\textdollar}§& th ); §\C{// [0,UINT\_MAX]}§8984 size_t prng( §thread\LstStringStyle{\textdollar}§ & th, size_t u ); §\C{// [0,u)}§8985 size_t prng( §thread\LstStringStyle{\textdollar}§ & th, size_t l, size_t u ); §\C{// [l,u]}§8823 void set_seed( uint32_t seed ); $\C[3.75in]{// set global seed}$ 8824 uint32_t get_seed(); §\C{// get global seed}§ 8825 // SLOWER 8826 uint32_t prng(); §\C{// [0,UINT\_MAX]}§ 8827 uint32_t prng( uint32_t u ); §\C{// [0,u)}§ 8828 uint32_t prng( uint32_t l, uint32_t u ); §\C{// [l,u]}§ 8829 // FASTER 8830 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th ); §\C{// [0,UINT\_MAX]}§ 8831 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th, uint32_t u ); §\C{// [0,u)}§ 8832 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th, uint32_t l, uint32_t u ); §\C{// [l,u]}\CRT§ 8986 8833 \end{cfa} 8987 8834 The only difference between the two sets of ©prng© routines is performance. … … 8994 8841 Hence, these threads generate different sequences of random numbers. 8995 8842 If each thread needs its own seed, use a sequential ©PRNG© in each thread. 8996 The slower ©prng© global functions, \ie \emph{without} a thread argument, call ©active_thread© internally to indirectly access the current thread's PRNG state, while the faster ©prng© functions, \ie \emph{with} a thread argument,directly access the thread through the thread parameter.8843 The slower ©prng© functions \emph{without} a thread argument call ©active_thread© internally to indirectly access the current thread's PRNG state, while the faster ©prng© functions \emph{with} a thread argument directly access the thread through the thread parameter. 8997 8844 If a thread pointer is available, \eg in thread main, eliminating the call to ©active_thread© significantly reduces the cost of accessing the thread's PRNG state. 8998 8845 \VRef[Figure]{f:ConcurrentPRNG} shows an example using the slower/faster concurrent PRNG in the program main and a thread. … … 9009 8856 int main() { 9010 8857 set_seed( 1009 ); 9011 §\R{thread\LstStringStyle{\textdollar}}§®& th = *active_thread()®; // program-main thread-address8858 $\R{thread\LstStringStyle{\textdollar}}$ ®& th = *active_thread()®; // program-main thread-address 9012 8859 for ( i; 10 ) { 9013 8860 sout | nlOff | ®prng()®; sout | ®prng( 5 )®; sout | ®prng( 0, 5 )® | '\t'; // SLOWER … … 9232 9079 \hline 9233 9080 \begin{cfa} 9234 #include <gmp.h> §\indexc{gmp.h}§9081 #include <gmp.h>$\indexc{gmp.h}$ 9235 9082 int main( void ) { 9236 9083 ®gmp_printf®( "Factorial Numbers\n" ); … … 9246 9093 & 9247 9094 \begin{cfa} 9248 #include <gmp.hfa> §\indexc{gmp}§9095 #include <gmp.hfa>$\indexc{gmp}$ 9249 9096 int main( void ) { 9250 9097 sout | "Factorial Numbers"; … … 9318 9165 \begin{cfa}[belowskip=0pt] 9319 9166 // implementation 9320 struct Rational { §\indexc{Rational}§9167 struct Rational {$\indexc{Rational}$ 9321 9168 long int numerator, denominator; §\C{// invariant: denominator > 0}§ 9322 9169 }; // Rational -
libcfa/src/collections/string_res.cfa
r32490deb rc75b30a 10 10 // Created On : Fri Sep 03 11:00:00 2021 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 22 23:12:42202413 // Update Count : 4312 // Last Modified On : Tue Jan 16 22:19:27 2024 13 // Update Count : 35 14 14 // 15 15 … … 263 263 bool cont = false; 264 264 265 _Istream_C widthcf = { cstr, (_Istream_str_base)f };265 _Istream_Cstr cf = { cstr, (_Istream_str_base)f }; 266 266 if ( ! cf.flags.rwd ) cf.wd = wd; 267 267 -
libcfa/src/fstream.cfa
r32490deb rc75b30a 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jan 28 09:56:08 202413 // Update Count : 55 412 // Last Modified On : Wed Nov 15 10:51:14 2023 13 // Update Count : 552 14 14 // 15 15 … … 209 209 void ?{}( ifstream & is, void * file ) with( is ) { 210 210 file$ = file; 211 nlOnOff$ = false; // => skip newlines when reading single characters211 nlOnOff$ = false; 212 212 } // ?{} 213 213 -
libcfa/src/iostream.cfa
r32490deb rc75b30a 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jan 28 11:58:54202413 // Update Count : 1 91712 // Last Modified On : Wed Jan 3 10:53:13 2024 13 // Update Count : 1898 14 14 // 15 15 … … 944 944 istype & nl( istype & is ) { 945 945 fmt( is, "%*[^\n]" ); // ignore characters to newline 946 if ( ! eof( is ) ) fmt( is, "%*c" );// read newline946 if ( ! eof( is ) && getANL$( is ) ) fmt( is, "%*c" ); // read newline 947 947 return is; 948 948 } // nl … … 984 984 } 985 985 986 istype & ?|?( istype & is, _Istream_Cquoted f ) with( f.cstr ) { 986 istype & ?|?( istype & is, _Istream_Cquoted f ) with( f ) { 987 char fmtstr[32]; // storage scanset and format codes 988 fmtstr[0] = '%'; 989 990 int pos = 1; 987 991 int args; 988 fini: { 992 bool check = true; 993 994 if ( cstr.flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; } 995 int rwd = cstr.wd; 996 if ( cstr.wd != -1 ) { // => just ignore versus ignore with width 997 // wd is buffer bytes available (for input chars + null terminator) 998 // rwd is count of input chars 999 // no maximum width necessary because text ignored => width is read width 1000 if ( cstr.flags.rwd ) check = false; 1001 else rwd = cstr.wd - 1; 1002 pos += sprintf( &fmtstr[pos], "%d", rwd ); 1003 } // if 1004 1005 int len = 0; // may not be set in fmt 1006 char enddelim; 1007 if ( ! cstr.flags.inex ) { // => quoted getline 989 1008 args = fmt( is, "%*[ \f\n\r\t\v]" ); // remove leading whitespace 990 if ( eof( is ) ) break fini; 991 char rfmt[4] = { delimiters[0], '%', 'n', '\0' }; 992 int len = 0; // may not be set in fmt 1009 if ( eof( is ) ) goto Eof; 1010 char rfmt[4] = { cstr.delimiters[0], '%', 'n', '\0' }; 993 1011 args = fmt( is, rfmt, &len ); // remove leading quote 994 if ( len == 0 || eof( is ) ) break fini; 995 996 // Change the remainder of the read into a getline by reseting the closing delimiter. 997 if ( delimiters[1] != '\0' ) { 998 delimiters[0] = delimiters[1]; 999 delimiters[1] = '\0'; 1012 if ( len == 0 || eof( is ) ) goto Eof; 1013 } // if 1014 enddelim = cstr.delimiters[1] == '\0' ? cstr.delimiters[0] : cstr.delimiters[1]; 1015 sprintf( &fmtstr[pos], "[^%c]%%n", enddelim ); 1016 if ( cstr.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*' 1017 else args = fmt( is, fmtstr, cstr.s, &len ); 1018 if ( check && len == rwd && ! eof( is ) ) { // might not fit 1019 char peek; 1020 fmt( is, "%c", &peek ); // check for delimiter 1021 if ( ! eof( is ) ) { 1022 if ( peek != enddelim ) { 1023 ungetc( is, peek ); 1024 throwResume ExceptionInst( cstring_length ); 1025 } // if 1000 1026 } // if 1001 flags.delimiter = true; 1002 return is | *(_Istream_Cstr *)&f; 1003 } // fini 1004 // read failed => no pattern match => set string to null 1005 if ( ! flags.ignore && s != 0p && args == 0 ) s[0] = '\0'; 1027 } else fmt( is, "%*c" ); // remove delimiter 1028 Eof: ; 1029 if ( rwd > 0 && args == 0 ) cstr.s[0] = '\0'; // read failed => no pattern match => set string to null 1006 1030 if ( args == 1 && eof( is ) ) { // data but scan ended at EOF 1007 1031 clear( is ); // => reset EOF => detect again on next read … … 1010 1034 } 1011 1035 1012 istype & ?|?( istype & is, _Istream_Cstr f ) with( f .cstr) {1036 istype & ?|?( istype & is, _Istream_Cstr f ) with( f ) { 1013 1037 const char * scanset; 1014 1038 size_t nscanset = 0; 1015 1039 if ( flags.delimiter ) scanset = delimiters; // getline ? 1016 else scanset = f. cstr.scanset;1040 else scanset = f.scanset; 1017 1041 if ( scanset ) nscanset = strlen( scanset ); 1018 1042 1019 1043 char fmtstr[nscanset + 32]; // storage for scanset and format codes 1020 1044 fmtstr[0] = '%'; 1045 1021 1046 int pos = 1; 1022 1047 int args; 1023 1048 bool check = true; 1024 1049 1025 if ( f lags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; }1026 int rwd = wd;1027 if ( wd != -1 ) { // => just ignore versus ignore with width1050 if ( f.flags.ignore ) { check = false; fmtstr[1] = '*'; pos += 1; } 1051 int rwd = f.wd; 1052 if ( f.wd != -1 ) { // => just ignore versus ignore with width 1028 1053 // wd is buffer bytes available (for input chars + null terminator) 1029 1054 // rwd is count of input chars 1030 1055 // no maximum width necessary because text ignored => width is read width 1031 if ( flags.rwd ) check = false; 1032 else rwd = wd - 1; 1033 assert( rwd > 0 ); 1056 if ( f.flags.rwd ) check = false; 1057 else rwd = f.wd - 1; 1034 1058 pos += sprintf( &fmtstr[pos], "%d", rwd ); 1035 1059 } // if 1036 1060 1037 1061 if ( ! scanset ) { // %s, %*s, %ws, %*ws 1038 // fprintf( stderr, "cstr %s\n", s );1062 // fprintf( stderr, "cstr %s\n", f.s ); 1039 1063 strcpy( &fmtstr[pos], "s%n" ); 1040 1064 int len = 0; // may not be set in fmt 1041 if ( f lags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'1042 else args = fmt( is, fmtstr, s, &len );1043 // fprintf( stderr, "cstr %s %d %d %d %s\n", fmtstr, args, len, wd,s );1065 if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*' 1066 else args = fmt( is, fmtstr, f.s, &len ); 1067 // fprintf( stderr, "cstr %s %d %d %d %s\n", fmtstr, args, len, f.wd, f.s ); 1044 1068 if ( check && len >= rwd && ! eof( is ) ) { // might not fit 1045 1069 char peek; … … 1052 1076 } // if 1053 1077 // FIX ME: CFA strings need to be modified to NOT change the argument for this case, then this can be removed. 1054 if ( ! flags.ignore && args == 0 ) s[0]= '\0';// read failed => no pattern match => set string to null1078 if ( rwd > 0 && args == 0 ) f.s[0]= '\0'; // read failed => no pattern match => set string to null 1055 1079 } else { 1056 if ( f lags.delimiter ) { // getline1080 if ( f.flags.delimiter ) { // getline 1057 1081 int len = 0; // may not be set in fmt 1058 if ( delimiters[2] != '\0' ) { // read single character ? 1059 sprintf( &fmtstr[pos], "c%%n" ); 1060 } else { 1061 sprintf( &fmtstr[pos], "[^%c]%%n", delimiters[0] ); 1062 } // if 1063 if ( flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*' 1064 else args = fmt( is, fmtstr, s, &len ); 1082 sprintf( &fmtstr[pos], "[^%c]%%n", f.delimiters[0] ); 1083 if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*' 1084 else args = fmt( is, fmtstr, f.s, &len ); 1065 1085 if ( check && len == rwd && ! eof( is ) ) { // might not fit 1066 char peek;1067 fmt( is, "%c", &peek ); // check fordelimiter1086 fmtstr[0] = f.delimiters[0]; fmtstr[1] = '%'; fmtstr[2] = 'n'; fmtstr[3] = '\0'; 1087 fmt( is, fmtstr, &len ); // remove delimiter 1068 1088 if ( ! eof( is ) ) { 1069 if ( peek != delimiters[0] ) { 1070 ungetc( is, peek ); 1089 // if ( peek != f.delimiter[0] ) { 1090 if ( len != 1 ) { 1091 // ungetc( is, peek ); 1071 1092 throwResume ExceptionInst( cstring_length ); 1072 1093 } // if … … 1076 1097 // incl %[xxx], %*[xxx], %w[xxx], %*w[xxx] 1077 1098 // excl %[^xxx], %*[^xxx], %w[^xxx], %*w[^xxx] 1078 sprintf( &fmtstr[pos], "[%s%s]%%n", f lags.inex ? "^" : "", scanset );1079 // fprintf( stderr, "incl/excl %s %d\n", fmtstr, wd );1099 sprintf( &fmtstr[pos], "[%s%s]%%n", f.flags.inex ? "^" : "", scanset ); 1100 // fprintf( stderr, "incl/excl %s %d\n", fmtstr, f.wd ); 1080 1101 int len = 0; // may not be set in fmt 1081 if ( f lags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*'1082 else args = fmt( is, fmtstr, s, &len );1083 // fprintf( stderr, "incl/excl %s \"%s\" %d %d %d %d %d %c\n", fmtstr, s, args, wd, len, eof( is ), check, s[wd] );1102 if ( f.flags.ignore ) args = fmt( is, fmtstr, &len ); // no string argument for '*' 1103 else args = fmt( is, fmtstr, f.s, &len ); 1104 // fprintf( stderr, "incl/excl %s \"%s\" %d %d %d %d %d %c\n", fmtstr, f.s, args, f.wd, len, eof( is ), check, f.s[f.wd] ); 1084 1105 if ( check && len == rwd && ! eof( is ) ) { // might not fit 1085 1106 // fprintf( stderr, "overflow\n" ); … … 1089 1110 if ( ! eof( is ) ) { 1090 1111 ungetc( is, peek ); 1091 if ( f lags.inex ^ strchr(scanset, peek ) != 0p ) throwResume ExceptionInst( cstring_length );1112 if ( f.flags.inex ^ strchr( f.scanset, peek ) != 0p ) throwResume ExceptionInst( cstring_length ); 1092 1113 } // if 1093 1114 } // if 1094 1115 } // if 1095 if ( ! flags.ignore && args == 0 ) s[0]= '\0';// read failed => no pattern match => set string to null1116 if ( rwd > 0 && args == 0 ) f.s[0]= '\0'; // read failed => no pattern match => set string to null 1096 1117 } // if 1097 1118 if ( args == 1 && eof( is ) ) { // data but scan ended at EOF … … 1099 1120 clear( is ); // => reset EOF => detect again on next read 1100 1121 } // if 1122 return is; 1123 } // ?|? 1124 1125 istype & ?|?( istype & is, _Istream_Char f ) { 1126 fmt( is, "%*c" ); // argument variable unused 1101 1127 return is; 1102 1128 } // ?|? … … 1119 1145 } // distribution 1120 1146 1121 INPUT_FMT_IMPL( char, "c" )1122 1147 INPUT_FMT_IMPL( signed char, "hhi" ) 1123 1148 INPUT_FMT_IMPL( unsigned char, "hhi" ) -
libcfa/src/iostream.hfa
r32490deb rc75b30a 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jan 28 11:56:29202413 // Update Count : 73312 // Last Modified On : Wed Jan 3 10:53:18 2024 13 // Update Count : 610 14 14 // 15 15 … … 196 196 // *********************************** integral *********************************** 197 197 198 // See 6.7.9. 19) The initialization shall occur in initializer list order, each initializer provided for a particular 199 // subobject overriding any previously listed initializer for the same subobject; ***all subobjects that are not 200 // initialized explicitly shall be initialized implicitly the same as objects that have static storage duration.*** 201 198 202 #define INTEGRAL_FMT_DECL( T, CODE ) \ 199 203 static inline { \ 200 _Ostream_Manip(T) bin( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base :'b', { .all : 0 } }; } \201 _Ostream_Manip(T) oct( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base :'o', { .all : 0 } }; } \202 _Ostream_Manip(T) hex( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base :'x', { .all : 0 } }; } \203 _Ostream_Manip(T) wd( unsigned int w d, T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : wd, .pc : 0, .base :CODE, { .all : 0 } }; } \204 _Ostream_Manip(T) wd( unsigned int w d, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : wd, .pc : pc, .base :CODE, { .flags.pc : true } }; } \205 _Ostream_Manip(T) & wd( unsigned int w d, _Ostream_Manip(T) & fmt ) { fmt.wd = wd; return fmt; } \206 _Ostream_Manip(T) & wd( unsigned int w d, unsigned int pc, _Ostream_Manip(T) & fmt ) { fmt.wd = wd; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \204 _Ostream_Manip(T) bin( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'b', { .all : 0 } }; } \ 205 _Ostream_Manip(T) oct( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'o', { .all : 0 } }; } \ 206 _Ostream_Manip(T) hex( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'x', { .all : 0 } }; } \ 207 _Ostream_Manip(T) wd( unsigned int w, T val ) { return (_Ostream_Manip(T))@{ val, w, 0, CODE, { .all : 0 } }; } \ 208 _Ostream_Manip(T) wd( unsigned int w, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, CODE, { .flags.pc : true } }; } \ 209 _Ostream_Manip(T) & wd( unsigned int w, _Ostream_Manip(T) & fmt ) { fmt.wd = w; return fmt; } \ 210 _Ostream_Manip(T) & wd( unsigned int w, unsigned int pc, _Ostream_Manip(T) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \ 207 211 _Ostream_Manip(T) & left( _Ostream_Manip(T) & fmt ) { fmt.flags.left = true; return fmt; } \ 208 212 _Ostream_Manip(T) & upcase( _Ostream_Manip(T) & fmt ) { if ( fmt.base == 'x' || fmt.base == 'b' ) fmt.base -= 32; /* upper case */ return fmt; } \ 209 213 _Ostream_Manip(T) & nobase( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \ 210 214 _Ostream_Manip(T) & pad0( _Ostream_Manip(T) & fmt ) { fmt.flags.pad0 = true; return fmt; } \ 211 _Ostream_Manip(T) sign( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base :CODE, { .flags.sign : true } }; } \215 _Ostream_Manip(T) sign( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, CODE, { .flags.sign : true } }; } \ 212 216 _Ostream_Manip(T) & sign( _Ostream_Manip(T) & fmt ) { fmt.flags.sign = true; return fmt; } \ 213 217 } /* distribution */ \ … … 237 241 #define FLOATING_POINT_FMT_DECL( T ) \ 238 242 static inline { \ 239 _Ostream_Manip(T) hex( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base : 'a', { .all : 0 } }; } \ 240 _Ostream_Manip(T) sci( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base : 'e', { .all : 0 } }; } \ 241 _Ostream_Manip(T) eng( T val ) { return (_Ostream_Manip(T))@{ .val : val, 1, -1, .base : 'g', { .flags.eng : true } }; } \ 242 _Ostream_Manip(T) wd( unsigned int wd, T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : wd, .pc : 0, .base : 'g', { .all : 0 } }; } \ 243 _Ostream_Manip(T) wd( unsigned int wd, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : wd, .pc : pc, .base : 'f', { .flags.pc : true } }; } \ 244 _Ostream_Manip(T) ws( unsigned int wd, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : wd, .pc : pc, .base : 'g', { .flags.pc : true } }; } \ 245 _Ostream_Manip(T) & wd( unsigned int wd, _Ostream_Manip(T) & fmt ) { if ( fmt.flags.eng ) fmt.base = 'f'; fmt.wd = wd; return fmt; } \ 246 _Ostream_Manip(T) & wd( unsigned int wd, unsigned int pc, _Ostream_Manip(T) & fmt ) { \ 247 if ( fmt.flags.eng ) fmt.base = 'f'; fmt.wd = wd; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \ 248 _Ostream_Manip(T) & ws( unsigned int wd, unsigned int pc, _Ostream_Manip(T) & fmt ) { fmt.wd = wd; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \ 243 _Ostream_Manip(T) hex( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'a', { .all : 0 } }; } \ 244 _Ostream_Manip(T) sci( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'e', { .all : 0 } }; } \ 245 _Ostream_Manip(T) eng( T val ) { return (_Ostream_Manip(T))@{ val, 1, -1, 'g', { .flags.eng : true } }; } \ 246 _Ostream_Manip(T) wd( unsigned int w, T val ) { return (_Ostream_Manip(T))@{ val, w, 0, 'g', { .all : 0 } }; } \ 247 _Ostream_Manip(T) wd( unsigned int w, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, 'f', { .flags.pc : true } }; } \ 248 _Ostream_Manip(T) ws( unsigned int w, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, 'g', { .flags.pc : true } }; } \ 249 _Ostream_Manip(T) & wd( unsigned int w, _Ostream_Manip(T) & fmt ) { if ( fmt.flags.eng ) fmt.base = 'f'; fmt.wd = w; return fmt; } \ 250 _Ostream_Manip(T) & wd( unsigned int w, unsigned int pc, _Ostream_Manip(T) & fmt ) { if ( fmt.flags.eng ) fmt.base = 'f'; fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \ 251 _Ostream_Manip(T) & ws( unsigned int w, unsigned int pc, _Ostream_Manip(T) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \ 249 252 _Ostream_Manip(T) & left( _Ostream_Manip(T) & fmt ) { fmt.flags.left = true; return fmt; } \ 250 _Ostream_Manip(T) upcase( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base :'G', { .all : 0 } }; } \253 _Ostream_Manip(T) upcase( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'G', { .all : 0 } }; } \ 251 254 _Ostream_Manip(T) & upcase( _Ostream_Manip(T) & fmt ) { fmt.base -= 32; /* upper case */ return fmt; } \ 252 255 _Ostream_Manip(T) & pad0( _Ostream_Manip(T) & fmt ) { fmt.flags.pad0 = true; return fmt; } \ 253 _Ostream_Manip(T) sign( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base :'g', { .flags.sign : true } }; } \256 _Ostream_Manip(T) sign( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'g', { .flags.sign : true } }; } \ 254 257 _Ostream_Manip(T) & sign( _Ostream_Manip(T) & fmt ) { fmt.flags.sign = true; return fmt; } \ 255 _Ostream_Manip(T) nodp( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base :'g', { .flags.nobsdp : true } }; } \258 _Ostream_Manip(T) nodp( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'g', { .flags.nobsdp : true } }; } \ 256 259 _Ostream_Manip(T) & nodp( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \ 257 _Ostream_Manip(T) unit( T val ) { return (_Ostream_Manip(T))@{ .val : val, .wd : 1, .pc : 0, .base :'g', { .flags.nobsdp : true } }; } \260 _Ostream_Manip(T) unit( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'g', { .flags.nobsdp : true } }; } \ 258 261 _Ostream_Manip(T) & unit( _Ostream_Manip(T) & fmt ) { fmt.flags.nobsdp = true; return fmt; } \ 259 262 } /* distribution */ \ … … 269 272 270 273 static inline { 271 _Ostream_Manip(char) bin( char c ) { return (_Ostream_Manip(char))@{ .val : c, .wd : 1, .pc : 0, .base :'b', { .all : 0 } }; }272 _Ostream_Manip(char) oct( char c ) { return (_Ostream_Manip(char))@{ .val : c, .wd : 1, .pc : 0, .base :'o', { .all : 0 } }; }273 _Ostream_Manip(char) hex( char c ) { return (_Ostream_Manip(char))@{ .val : c, .wd : 1, .pc : 0, .base :'x', { .all : 0 } }; }274 _Ostream_Manip(char) wd( unsigned int w d, char c ) { return (_Ostream_Manip(char))@{ c, wd, 0, .base :'c', { .all : 0 } }; }275 _Ostream_Manip(char) & wd( unsigned int w d, _Ostream_Manip(char) & fmt ) { fmt.wd = wd; return fmt; }274 _Ostream_Manip(char) bin( char c ) { return (_Ostream_Manip(char))@{ c, 1, 0, 'b', { .all : 0 } }; } 275 _Ostream_Manip(char) oct( char c ) { return (_Ostream_Manip(char))@{ c, 1, 0, 'o', { .all : 0 } }; } 276 _Ostream_Manip(char) hex( char c ) { return (_Ostream_Manip(char))@{ c, 1, 0, 'x', { .all : 0 } }; } 277 _Ostream_Manip(char) wd( unsigned int w, char c ) { return (_Ostream_Manip(char))@{ c, w, 0, 'c', { .all : 0 } }; } 278 _Ostream_Manip(char) & wd( unsigned int w, _Ostream_Manip(char) & fmt ) { fmt.wd = w; return fmt; } 276 279 _Ostream_Manip(char) & left( _Ostream_Manip(char) & fmt ) { fmt.flags.left = true; return fmt; } 277 280 _Ostream_Manip(char) & upcase( _Ostream_Manip(char) & fmt ) { if ( fmt.base == 'x' || fmt.base == 'b' ) fmt.base -= 32; /* upper case */ return fmt; } … … 286 289 287 290 static inline { 288 _Ostream_Manip(const char *) bin( const char s[] ) { return (_Ostream_Manip(const char *))@{ .val : s, .wd : 1, .pc : 0, .base :'b', { .all : 0 } }; }289 _Ostream_Manip(const char *) oct( const char s[] ) { return (_Ostream_Manip(const char *))@{ .val : s, .wd : 1, .pc : 0, .base :'o', { .all : 0 } }; }290 _Ostream_Manip(const char *) hex( const char s[] ) { return (_Ostream_Manip(const char *))@{ .val : s, .wd : 1, .pc : 0, .base :'x', { .all : 0 } }; }291 _Ostream_Manip(const char *) wd( unsigned int w d, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, wd, 0, .base :'s', { .all : 0 } }; }292 _Ostream_Manip(const char *) wd( unsigned int w d, unsigned int pc, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, .wd : wd, .pc : pc, .base :'s', { .flags.pc : true } }; }293 _Ostream_Manip(const char *) & wd( unsigned int w d, _Ostream_Manip(const char *) & fmt ) { fmt.wd = wd; return fmt; }294 _Ostream_Manip(const char *) & wd( unsigned int w d, unsigned int pc, _Ostream_Manip(const char *) & fmt ) { fmt.wd = wd; fmt.pc = pc; fmt.flags.pc = true; return fmt; }291 _Ostream_Manip(const char *) bin( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'b', { .all : 0 } }; } 292 _Ostream_Manip(const char *) oct( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'o', { .all : 0 } }; } 293 _Ostream_Manip(const char *) hex( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'x', { .all : 0 } }; } 294 _Ostream_Manip(const char *) wd( unsigned int w, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, 0, 's', { .all : 0 } }; } 295 _Ostream_Manip(const char *) wd( unsigned int w, unsigned int pc, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, pc, 's', { .flags.pc : true } }; } 296 _Ostream_Manip(const char *) & wd( unsigned int w, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; return fmt; } 297 _Ostream_Manip(const char *) & wd( unsigned int w, unsigned int pc, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } 295 298 _Ostream_Manip(const char *) & left( _Ostream_Manip(const char *) & fmt ) { fmt.flags.left = true; return fmt; } 296 299 _Ostream_Manip(const char *) & nobase( _Ostream_Manip(const char *) & fmt ) { fmt.flags.nobsdp = true; return fmt; } … … 382 385 383 386 static inline { 384 _Istream_Cskip skip( const char scanset[] ) { return (_Istream_Cskip)@{ .scanset : scanset, .wd :0 }; }385 _Istream_Cskip skip( unsigned int wd ) { return (_Istream_Cskip)@{ .scanset : 0p, .wd :wd }; }387 _Istream_Cskip skip( const char scanset[] ) { return (_Istream_Cskip)@{ scanset, 0 }; } 388 _Istream_Cskip skip( unsigned int wd ) { return (_Istream_Cskip)@{ 0p, wd }; } 386 389 } // distribution 387 390 … … 397 400 unsigned char ignore:1; // do not change input argument 398 401 unsigned char inex:1; // include/exclude characters in scanset 399 unsigned char delimiter:1; // delimit character (s)402 unsigned char delimiter:1; // delimit character 400 403 unsigned char rwd:1; // read width 401 404 } flags; … … 403 406 }; // _Istream_str_base 404 407 405 struct _Istream_C width{408 struct _Istream_Cstr { 406 409 char * s; 407 410 inline _Istream_str_base; 408 411 }; // _Istream_Cstr 409 412 410 // Restrict nesting of input manipulators to those combinations that make sense.411 412 struct _Istream_Cstr {413 _Istream_Cwidth cstr;414 }; // _Istream_Cstr415 416 413 struct _Istream_Cquoted { 417 _Istream_C widthcstr;414 _Istream_Cstr cstr; 418 415 }; // _Istream_Cquoted 419 416 420 417 static inline { 421 // width must include room for null terminator, (gcc) scanf does not allow a 0 width => wd > 1 (1 char and null) and rd > 0 (1 char); 422 _Istream_Cwidth wdi( unsigned int wd, char s[] ) { 423 if ( wd <= 1 ) throw (cstring_length){ &cstring_length_vt }; // minimum 1 character and null terminator 424 return (_Istream_Cwidth)@{ .s : s, { {.scanset : 0p}, .wd : wd, {.all : 0} } }; 418 // width must include room for null terminator 419 _Istream_Cstr wdi( unsigned int wd, char s[] ) { return (_Istream_Cstr)@{ s, { {0p}, wd, {.all : 0} } }; } 420 _Istream_Cstr wdi( unsigned int wd, unsigned int rwd, char s[] ) { 421 if ( wd <= rwd ) throw (cstring_length){ &cstring_length_vt }; 422 return (_Istream_Cstr)@{ s, { {0p}, rwd, {.flags.rwd : true} } }; 425 423 } 426 _Istream_C width wdi( unsigned int wd, unsigned int rwd, char s[]) {427 if ( wd <= 1 || wd <= rwd ) throw (cstring_length){ &cstring_length_vt }; // minimum 1 character, null terminator, plus subset428 return (_Istream_C width)@{ .s : s, { {.scanset : 0p}, .wd : rwd, {.flags.rwd : true} } };424 _Istream_Cquoted & quoted( _Istream_Cstr & fmt, const char Ldelimiter = '"', const char Rdelimiter = '\0' ) { 425 fmt.delimiters[0] = Ldelimiter; fmt.delimiters[1] = Rdelimiter; fmt.delimiters[2] = '\0'; 426 return (_Istream_Cquoted &)fmt; 429 427 } 430 _Istream_C quoted quoted( char & ch, const char Ldelimiter = '\'', const char Rdelimiter = '\0' ) {431 return (_Istream_Cquoted)@{ { .s : &ch, { {.delimiters : { Ldelimiter, Rdelimiter, '\1' }}, .wd : 1, {.flags.rwd : true} } } };428 _Istream_Cstr & getline( _Istream_Cstr & fmt, const char delimiter = '\n' ) { 429 fmt.delimiters[0] = delimiter; fmt.delimiters[1] = '\0'; fmt.flags.delimiter = true; fmt.flags.inex = true; return fmt; 432 430 } 433 _Istream_Cquoted & quoted( _Istream_Cwidth & f, const char Ldelimiter = '"', const char Rdelimiter = '\0' ) { 434 f.delimiters[0] = Ldelimiter; f.delimiters[1] = Rdelimiter; f.delimiters[2] = '\0'; 435 return (_Istream_Cquoted &)f; 436 } 437 _Istream_Cstr & getline( _Istream_Cwidth & f, const char delimiter = '\n' ) { 438 f.delimiters[0] = delimiter; f.delimiters[1] = '\0'; f.flags.delimiter = true; return (_Istream_Cstr &)f; 439 } 440 _Istream_Cstr & incl( const char scanset[], _Istream_Cwidth & f ) { f.scanset = scanset; f.flags.inex = false; return (_Istream_Cstr &)f; } 441 _Istream_Cstr & excl( const char scanset[], _Istream_Cwidth & f ) { f.scanset = scanset; f.flags.inex = true; return (_Istream_Cstr &)f; } 442 _Istream_Cstr ignore( const char s[] ) { return (_Istream_Cwidth)@{ .s : (char *)s, { {.scanset : 0p}, .wd : -1, {.flags.ignore : true} } }; } 443 _Istream_Cstr & ignore( _Istream_Cwidth & f ) { f.flags.ignore = true; return (_Istream_Cstr &)f; } 444 _Istream_Cquoted & ignore( _Istream_Cquoted & f ) { f.cstr.flags.ignore = true; return (_Istream_Cquoted &)f; } 445 _Istream_Cstr & ignore( _Istream_Cstr & f ) { f.cstr.flags.ignore = true; return (_Istream_Cstr &)f; } 431 _Istream_Cstr & incl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; } 432 _Istream_Cstr & excl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; } 433 _Istream_Cstr ignore( char s[] ) { return (_Istream_Cstr)@{ s, { {0p}, -1, {.flags.ignore : true} } }; } 434 _Istream_Cstr & ignore( _Istream_Cstr & fmt ) { fmt.flags.ignore = true; return fmt; } 446 435 } // distribution 447 436 448 437 forall( istype & | basic_istream( istype ) ) { 438 istype & ?|?( istype & is, _Istream_Cstr f ); 449 439 istype & ?|?( istype & is, _Istream_Cskip f ); 450 440 istype & ?|?( istype & is, _Istream_Cquoted f ); 451 istype & ?|?( istype & is, _Istream_Cstr f ); 452 static inline { 453 istype & ?|?( istype & is, _Istream_Cwidth f ) { return is | *(_Istream_Cstr *)&f; } 454 } // distribution 455 } // distribution 441 } // distribution 442 443 struct _Istream_Char { 444 bool ignore; // do not change input argument 445 }; // _Istream_Char 446 447 static inline { 448 _Istream_Char ignore( const char ) { return (_Istream_Char)@{ true }; } 449 _Istream_Char & ignore( _Istream_Char & fmt ) { fmt.ignore = true; return fmt; } 450 } // distribution 451 forall( istype & | basic_istream( istype ) ) { 452 istype & ?|?( istype & is, _Istream_Char f ); 453 } 456 454 457 455 forall( T & | sized( T ) ) … … 464 462 #define INPUT_FMT_DECL( T ) \ 465 463 static inline { \ 466 _Istream_Manip(T) wdi( unsigned int wd, T & val ) { return (_Istream_Manip(T))@{ .val : val, .wd : wd, .ignore : false }; } \ 467 _Istream_Manip(T) ignore( const T & val ) { return (_Istream_Manip(T))@{ .val : (T &)val, .wd : -1, .ignore : true }; } \ 464 _Istream_Manip(T) ignore( const T & val ) { return (_Istream_Manip(T))@{ (T &)val, -1, true }; } \ 468 465 _Istream_Manip(T) & ignore( _Istream_Manip(T) & fmt ) { fmt.ignore = true; return fmt; } \ 466 _Istream_Manip(T) wdi( unsigned int wd, T & val ) { return (_Istream_Manip(T))@{ val, wd, false }; } \ 467 _Istream_Manip(T) & wdi( unsigned int wd, _Istream_Manip(T) & fmt ) { fmt.wd = wd; return fmt; } \ 469 468 } /* distribution */ \ 470 469 forall( istype & | basic_istream( istype ) ) { \ … … 472 471 } // ?|? 473 472 474 INPUT_FMT_DECL( char )475 473 INPUT_FMT_DECL( signed char ) 476 474 INPUT_FMT_DECL( unsigned char ) -
src/Common/utility.h
r32490deb rc75b30a 111 111 }; 112 112 113 // ----------------------------------------------------------------------------- 114 // O(1) polymorphic integer ilog2, using clz, which returns the number of leading 0-bits, starting at the most 115 // significant bit (single instruction on x86) 116 117 template<typename T> 118 inline 119 #if defined(__GNUC__) && __GNUC__ > 4 120 constexpr 121 #endif 122 T ilog2(const T & t) { 123 if(std::is_integral<T>::value) { 124 const constexpr int r = sizeof(t) * __CHAR_BIT__ - 1; 125 if( sizeof(T) == sizeof(unsigned int) ) return r - __builtin_clz ( t ); 126 if( sizeof(T) == sizeof(unsigned long) ) return r - __builtin_clzl ( t ); 127 if( sizeof(T) == sizeof(unsigned long long) ) return r - __builtin_clzll( t ); 128 } 129 assert(false); 130 return -1; 131 } // ilog2 132 113 133 // Local Variables: // 114 134 // tab-width: 4 // -
src/ResolvExpr/Resolver.cc
r32490deb rc75b30a 50 50 51 51 namespace ResolvExpr { 52 template< typename iterator_t > 53 inline bool advance_to_mutex( iterator_t & it, const iterator_t & end ) { 54 while( it != end && !(*it)->get_type()->get_mutex() ) { 55 it++; 56 } 57 58 return it != end; 59 } 60 52 61 namespace { 53 62 /// Finds deleted expressions in an expression tree -
tests/collections/.expect/string-istream-manip.txt
r32490deb rc75b30a 68 68 12 wwwwwwww 69 69 13 wwwwwwww 70 14 70 14 cccc 71 71 15 72 72 1 yyyyyyyyyyyyyyyyyyyy … … 83 83 12 wwwwwwww 84 84 13 wwwwwwww 85 14 85 14 cccc 86 86 15 -
tests/collections/.in/string-istream-manip.txt
r32490deb rc75b30a 36 36 abcxxx 37 37 abcyyy 38 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww aaaaaaaawwwwwwww39 uuuuu 38 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww 39 uuuuuccccuuuuu 40 40 abc 41 41 cccccb … … 43 43 abcxxx 44 44 abcyyy 45 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww aaaaaaaawwwwwwww46 uuuuu 45 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww 46 uuuuuccccuuuuu -
tests/collections/string-istream-manip.cfa
r32490deb rc75b30a 165 165 sin | ignore( incl( "abc", wdi( 8, s ) ) ); sout | "12" | s; 166 166 sin | ignore( excl( "abc", wdi( 8, s ) ) ); sout | "13" | s; 167 sin | "\n";168 167 169 168 s = "q"; … … 192 191 sin | ignore( incl( "abc", wdi( 8, s ) ) ); sout | "12" | s; 193 192 sin | ignore( excl( "abc", wdi( 8, s ) ) ); sout | "13" | s; 194 sin | "\n";195 193 196 194 s = "q"; -
tests/io/.expect/manipulatorsInput.arm64.txt
r32490deb rc75b30a 18 18 12 wwwwwwww 19 19 13 wwwwwwww 20 14 rc= 0, q20 14 rc=1, cccc 21 21 15 rc=0, q 22 22 16 get this line 23 23 17 @# this line 1)-{} 24 18 @# this line 1)-{} 25 19 abc 26 20 abc 27 21 d d 24 18 abc 25 19 abc 26 20 d d 28 27 29 28 d 30 22 ZC44% 31 23 ZC44% 32 24 x 33 25 x 34 26 x 35 27 x 36 28 x 29 21 ZC44% 37 30 1 yyyyyyyyyyyyyyyyyyyy 38 31 2 abcxxx 39 32 3 abcxxx 40 33 4 aaaaaaaa 41 5 aaaaaaaa34 5 42 35 6 aabbccbb 43 36 7 dddwww 44 8 dddwww45 9 dddwww37 8 38 9 46 39 10 aaaaaaaa 47 40 11 wwwwwwww 48 12 wwwwwwww49 13 wwwwwwww50 14 41 12 42 13 43 14 cccc 51 44 15 52 45 16 get this line 53 46 17 @# this line 1)-{} 54 18 @# this line 1)-{} 55 19 abc 56 20 abc 57 21 d d 47 18 abc 48 19 abc 49 20 d d 58 50 59 51 d 60 22 ZC44% 61 23 ZC44% 62 24 x 63 25 x 64 26 x 65 27 x 66 28 x 52 21 ZC44% 67 53 a 68 54 a 69 xxx70 xxx71 55 -1 72 56 15 -
tests/io/.expect/manipulatorsInput.x64.txt
r32490deb rc75b30a 18 18 12 wwwwwwww 19 19 13 wwwwwwww 20 14 rc= 0, q20 14 rc=1, cccc 21 21 15 rc=0, q 22 22 16 get this line 23 23 17 @# this line 1)-{} 24 18 @# this line 1)-{} 25 19 abc 26 20 abc 27 21 d d 24 18 abc 25 19 abc 26 20 d d 28 27 29 28 d 30 22 ZC44% 31 23 ZC44% 32 24 x 33 25 x 34 26 x 35 27 x 36 28 x 29 21 ZC44% 37 30 1 yyyyyyyyyyyyyyyyyyyy 38 31 2 abcxxx 39 32 3 abcxxx 40 33 4 aaaaaaaa 41 5 aaaaaaaa34 5 42 35 6 aabbccbb 43 36 7 dddwww 44 8 dddwww45 9 dddwww37 8 38 9 46 39 10 aaaaaaaa 47 40 11 wwwwwwww 48 12 wwwwwwww49 13 wwwwwwww50 14 41 12 42 13 43 14 cccc 51 44 15 52 45 16 get this line 53 46 17 @# this line 1)-{} 54 18 @# this line 1)-{} 55 19 abc 56 20 abc 57 21 d d 47 18 abc 48 19 abc 49 20 d d 58 50 59 51 d 60 22 ZC44% 61 23 ZC44% 62 24 x 63 25 x 64 26 x 65 27 x 66 28 x 52 21 ZC44% 67 53 a 68 54 a 69 xxx70 xxx71 55 -1 72 56 15 -
tests/io/.expect/manipulatorsInput.x86.txt
r32490deb rc75b30a 18 18 12 wwwwwwww 19 19 13 wwwwwwww 20 14 rc= 0, q20 14 rc=1, cccc 21 21 15 rc=0, q 22 22 16 get this line 23 23 17 @# this line 1)-{} 24 18 @# this line 1)-{} 25 19 abc 26 20 abc 27 21 d d 24 18 abc 25 19 abc 26 20 d d 28 27 29 28 d 30 22 ZC44% 31 23 ZC44% 32 24 x 33 25 x 34 26 x 35 27 x 36 28 x 29 21 ZC44% 37 30 1 yyyyyyyyyyyyyyyyyyyy 38 31 2 abcxxx 39 32 3 abcxxx 40 33 4 aaaaaaaa 41 5 aaaaaaaa34 5 42 35 6 aabbccbb 43 36 7 dddwww 44 8 dddwww45 9 dddwww37 8 38 9 46 39 10 aaaaaaaa 47 40 11 wwwwwwww 48 12 wwwwwwww49 13 wwwwwwww50 14 41 12 42 13 43 14 cccc 51 44 15 52 45 16 get this line 53 46 17 @# this line 1)-{} 54 18 @# this line 1)-{} 55 19 abc 56 20 abc 57 21 d d 47 18 abc 48 19 abc 49 20 d d 58 50 59 51 d 60 22 ZC44% 61 23 ZC44% 62 24 x 63 25 x 64 26 x 65 27 x 66 28 x 52 21 ZC44% 67 53 a 68 54 a 69 xxx70 xxx71 55 -1 72 56 15 -
tests/io/.in/manipulatorsInput.txt
r32490deb rc75b30a 8 8 abcxxx 9 9 abcyyy 10 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww aaaaaaaawwwwwwww11 uuuuu 10 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww 11 uuuuuccccuuuuu 12 12 get this line 13 13 @# this line 1)-{}% 14 @# this line 2)-{}%15 14 "abc" 16 15 'abc ' … … 19 18 d } 20 19 X ZC44%Y 21 X ZC55%Y22 'x'23 "x"24 {x}25 XxY26 XyY27 20 abc 28 21 cccccb … … 30 23 abcxxx 31 24 abcyyy 32 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww aaaaaaaawwwwwwww33 uuuuu 25 aaaaaaaaxxxxxxxxaabbccbbdddwwwbbbbbbbbwwwwwwwwaaaaaaaawwwwwwww 26 uuuuuccccuuuuu 34 27 get this line 35 28 @# this line 1)-{}% 36 @# this line 2)-{}%37 29 "abc" 38 30 'abc ' … … 41 33 d } 42 34 X ZC44%Y 43 X ZC55%Y44 'x'45 "x"46 {x}47 XxY48 XyY49 35 ab 50 xxxyyy51 36 0xff 017 15-15 52 37 0xff 017 15-15 -
tests/io/manipulatorsInput.cfa
r32490deb rc75b30a 7 7 // Created On : Sat Jun 8 17:58:54 2019 8 8 // Last Modified By : Peter A. Buhr 9 // Last Modified On : Sun Jan 28 11:59:55202410 // Update Count : 1 339 // Last Modified On : Wed Jan 3 11:15:04 2024 10 // Update Count : 103 11 11 // 12 12 … … 55 55 } 56 56 { 57 char s[] = "yyyyyyyyyyyyyyyyyyyy"; // Input characters consumed:57 char s[] = "yyyyyyyyyyyyyyyyyyyy"; 58 58 const char sk_fmt[] = "%*[abc]"; 59 scanf( "abc " ); scanf( sk_fmt ); for ( 5 ) scanf( "%*c" ); printf( "1 %s\n", s ); // |abc |\ncccccb| \nxx\n| 60 scanf( "%s", s ); printf( "2 %s\n", s ); // |abcxxx| 61 scanf( "%*s" ); printf( "3 %s\n", s ); // |\nabcyyy| 62 scanf( "%8s", s ); printf( "4 %s\n", s ); // |\naaaaaaaa| 63 scanf( "%*8s" ); printf( "5 %s\n", s ); // |xxxxxxxx| 64 65 scanf( "%[abc]", s ); printf( "6 %s\n", s ); // |aabbccbb| 66 scanf( "%[^abc]", s ); printf( "7 %s\n", s ); // |dddwww| 67 scanf( "%*[abc]" ); printf( "8 %s\n", s ); // |bbbbbbbb| 68 scanf( "%*[^abc]" ); printf( "9 %s\n", s ); // |wwwwwwww| 69 scanf( "%8[abc]", s ); printf( "10 %s\n", s ); // |aaaaaaaa| 70 scanf( "%8[^abc]", s ); printf( "11 %s\n", s ); // |wwwwwwww| 71 scanf( "%*8[abc]" ); printf( "12 %s\n", s ); // |aaaaaaaa| 72 scanf( "%*8[^abc]" ); printf( "13 %s\n", s ); // |wwwwwwww| 73 scanf( "\n" ); // must start next line // |\n| 59 scanf( "abc " ); scanf( sk_fmt ); for ( 5 ) scanf( "%*c" ); printf( "1 %s\n", s ); 60 scanf( "%s", s ); printf( "2 %s\n", s ); 61 scanf( "%*s" ); printf( "3 %s\n", s ); 62 scanf( "%8s", s ); printf( "4 %s\n", s ); 63 scanf( "%*8s" ); printf( "5 %s\n", s ); 64 65 scanf( "%[abc]", s ); printf( "6 %s\n", s ); 66 scanf( "%[^abc]", s ); printf( "7 %s\n", s ); 67 scanf( "%*[abc]" ); printf( "8 %s\n", s ); 68 scanf( "%*[^abc]" ); printf( "9 %s\n", s ); 69 scanf( "%8[abc]", s ); printf( "10 %s\n", s ); 70 scanf( "%8[^abc]", s ); printf( "11 %s\n", s ); 71 scanf( "%*8[abc]" ); printf( "12 %s\n", s ); 72 scanf( "%*8[^abc]" ); printf( "13 %s\n", s ); 74 73 75 74 int rc; 76 75 s[0] = 'q'; s[1] = '\0'; rc = 99; 77 rc = scanf( "%[abc]", s ); printf( "14 rc=%d, %s\n", rc, s ); // ||76 rc = scanf( "%[abc]", s ); printf( "14 rc=%d, %s\n", rc, s ); 78 77 s[0] = 'q'; s[1] = '\0'; rc = 99; 79 rc = scanf( "%[^u]", s ); printf( "15 rc=%d, %s\n", rc, s ); // || 80 scanf( "%*[u]\n" ); // |uuuuu\n| 81 scanf( "%[^\n]\n", s ); printf( "16 %s\n", s ); // |get this line\n| 82 scanf( "%[^%%]%%\n", s ); printf( "17 %s\n", s ); // |@# this line 1)-{}%\n| 83 scanf( "%*[^%%]%%\n", s ); printf( "18 %s\n", s ); // |@# this line 1)-{}%\n| 84 85 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // || 86 scanf( "\"%[^\"]\"", s ); printf( "19 %s\n", s ); // |"abc"| 87 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 88 scanf( "'%[^']'", s ); printf( "20 %s\n", s ); // |'abc '| 89 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 90 scanf( "{%[^}]}", s ); printf( "21 %s\n", s ); // |{ d d\n\nd }| 91 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 92 scanf( "X%[^Y]Y", s ); printf( "22 %s\n", s ); // |X ZC44%Y| 93 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 94 scanf( "X%*[^Y]Y", s ); printf( "23 %s\n", s ); // |X ZC44%Y| 95 scanf( "\n" ); // must start next line // |\n| 96 97 char ch; 98 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 99 scanf( "'%c'", &ch ); printf( "24 %c\n", ch ); // |x| 100 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 101 scanf( "\"%c\"", &ch ); printf( "25 %c\n", ch ); // |x| 102 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 103 scanf( "{%c}", &ch ); printf( "26 %c\n", ch ); // |x| 104 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 105 scanf( "X%cY", &ch ); printf( "27 %c\n", ch ); // |x| 106 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace // |\n| 107 scanf( "X%*cY", &ch ); printf( "28 %c\n", ch ); // |x| 108 scanf( "\n" ); // must start next line // |\n| 78 rc = scanf( "%[^u]", s ); printf( "15 rc=%d, %s\n", rc, s ); 79 scanf( "%*[u]\n" ); 80 scanf( "%[^\n]\n", s ); printf( "16 %s\n", s ); 81 scanf( "%[^%%]%%\n", s ); printf( "17 %s\n", s ); 82 83 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace 84 scanf( "\"%[^\"]\"", s ); printf( "18 %s\n", s ); 85 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace 86 scanf( "'%[^']'", s ); printf( "19 %s\n", s ); 87 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace 88 scanf( "{%[^}]}", s ); printf( "20 %s\n", s ); 89 scanf( "%*[ \f\n\r\t\v]" ); // ignore whitespace 90 scanf( "X%[^Y]Y", s ); printf( "21 %s\n", s ); 91 scanf( "\n" ); // must start next line 109 92 } 110 93 { … … 125 108 sin | ignore( incl( "abc", wdi( sizeof(s), 8, s ) ) ); sout | "12" | s; 126 109 sin | ignore( excl( "abc", wdi( sizeof(s), 8, s ) ) ); sout | "13" | s; 127 sin | nl;128 110 129 111 s[0] = 'q'; s[1] = '\0'; … … 134 116 sin | getline( wdi( sizeof(s), s ) ); sout | "16" | s; 135 117 sin | getline( wdi( sizeof(s), s ), '%' ) | "\n"; sout | "17" | s; 136 sin | ignore( getline( wdi( sizeof(s), s ), '%' ) ) | "\n"; sout | "18" | s; 137 138 sin | quoted( wdi( sizeof(s), s ) ); sout | "19" | s; 139 sin | quoted( wdi( sizeof(s), s ), '\'' ); sout | "20" | s; 140 sin | quoted( wdi( sizeof(s), s ), '{', '}' ); sout | "21" | s; 141 sin | quoted( wdi( sizeof(s), s ), 'X', 'Y' ); sout | "22" | s; 142 sin | ignore( quoted( wdi( sizeof(s), s ), 'X', 'Y' ) ); sout | "23" | s; 143 144 char ch; 145 sin | quoted( ch ); sout | "24 " | ch; 146 sin | quoted( ch, '\"' ); sout | "25 " | ch; 147 sin | quoted( ch, '{', '}' ); sout | "26 " | ch; 148 sin | quoted( ch, 'X', 'Y' ); sout | "27 " | ch; 149 sin | ignore( quoted( ch, 'X', 'Y' ) ); sout | "28 " | ch; 150 sin | nl; 151 } 152 // Keep harmonized with collections/string-istream-manip 118 119 sin | quoted( wdi( sizeof(s), s ) ); sout | "18" | s; 120 sin | quoted( wdi( sizeof(s), s ), '\'' ); sout | "19" | s; 121 sin | quoted( wdi( sizeof(s), s ), '{', '}' ); sout | "20" | s; 122 sin | quoted( wdi( sizeof(s), s ), 'X', 'Y' ); sout | "21" | s; 123 } 124 // Keep harmonized with collections/string-istream-manip 153 125 { 154 126 char c; 155 127 sin | c; sout | c; 156 128 sin | ignore( c ); sout | c; 157 sin | nl;158 159 char ca[3] = { 'a', 'b', 'c' };160 sin | wdi( sizeof(ca), ca[0] ); sout | ca[0] | ca[1] | ca[2];161 sin | ignore( wdi( sizeof(ca), ca[0] ) ); sout | ca[0] | ca[1] | ca[2];162 sin | nl;163 129 164 130 signed char sc;
Note:
See TracChangeset
for help on using the changeset viewer.